2016-02-05 87 views
2

我爲什麼下面的代碼不起作用困惑:嵌套繼承的問題 - 如何初始化父類?

class ComparativeAnnotatorConfiguration(HashableNamespace): 
    """ 
    Takes the initial configuration from the main driver script and builds paths to all files that will be produced 
    by these tasks. 
    """ 
    def __init__(self, args, gene_set, query_genome_files, target_genome_files, annot_files, transmap): 
     self.work_dir = os.path.join(args.workDir, 'comparativeAnnotator', gene_set.sourceGenome, gene_set.geneSet) 
     self.metrics_dir = os.path.join(args.outputDir, 'metrics') 
     self.tx_set_dir = os.path.join(args.outputDir, 'tm_transcript_set') 
     self.reference = self.Reference(args, query_genome_files, annot_files, self.work_dir) 
     self.transmap = self.TransMap(args, query_genome_files, target_genome_files, annot_files, transmap, self.work_dir) 

    class Reference(HashableNamespace): 
     """ 
     The args object that will be passed directly to jobTree 
     """ 
     def __init__(self, args, query_genome_files, annot_files, out_dir): 
      self.__dict__.update(vars(args.jobTreeOptions)) 
      self.outDir = out_dir 
      self.refGenome = query_genome_files.genome 
      self.refFasta = query_genome_files.genome_fasta 
      self.sizes = query_genome_files.chrom_sizes 
      self.annotationGp = annot_files.gp 
      self.gencodeAttributes = annot_files.attributes 
      self.mode = 'reference' 

    class TransMap(Reference): 
     """ 
     The args object that will be passed directly to jobTree 
     """ 
     def __init__(self, args, query_genome_files, target_genome_files, annot_files, transmap, out_dir): 
      super(self.__class__, self).Reference.__init__(self, args, query_genome_files, annot_files, out_dir) 
      self.genome = target_genome_files.genome 
      self.psl = transmap.psl 
      self.refPsl = annot_files.psl 
      self.targetGp = transmap.gp 
      self.fasta = target_genome_files.fasta 
      self.mode = 'transMap' 

試圖實例化導致的錯誤:

AttributeError: 'super' object has no attribute 'Reference' 

我已經嘗試了不同的版本,如super(TransMap, self).Reference.__init__Reference.__init__,但所有給不同版本的NameError。如何比這裏列出的簡單的情況下,這種不同:

Using super() in nested classes

+2

'超(個體經營.__ class__,個體經營)。 __init__ ...'應該足夠了。 'super'的結果已經是'Reference' – fjarri

+2

不,不要將'self____ class__'傳遞給'super()'。如果你將這個類繼承下來,它會變得糟糕。 – Kevin

+0

你有沒有試過這個超級(TransMap,self).__ init __(#你的arg) – dlmeetei

回答

3

你想這樣的:

super(ComparativeAnnotatorConfiguration.TransMap, self).__init__(...) 

這是Python的類作用域規則的結果:類變量不在裏面方法的範圍。這並不僅僅因爲你的「變量」本身就是一個類。就Python而言,這完全一樣。

在Python 3,您可以編寫簡單得多:

super().__init__(...) 

這是又一個理由去升級。

-1
super(self.__class__, self).__init__() 

將調用父類的__init__方法。

+3

**不要那樣做**。如果您繼承當前課程,它會行爲不端。 'super()'的第一個參數應該(幾乎)總是一個導入時間常量,而不是通過檢查'self'找出的東西。 – Kevin

+0

@Kevin,是的,我明白了,對不起,我不是這個意思,是的,還有其他的缺點,使用它,是直接使用'super().__ init __(...)但仍然感謝讓我正確 –

0

你可以使用super(ChildClass, self).__init__()

class BaseClass(object): 
    def __init__(self, *args, **kwargs): 
     pass 

class ChildClass(BaseClass): 
    def __init__(self, *args, **kwargs): 
     super(ChildClass, self).__init__(*args, **kwargs) 

樣品繼承和初始化父類的構造代碼:

class Car(object): 
    condition = "new" 

    def __init__(self, model, color, mpg): 
     self.model = model 
     self.color = color 
     self.mpg = mpg 

class ElectricCar(Car): 
    def __init__(self, battery_type, model, color, mpg): 
     self.battery_type=battery_type 
     super(ElectricCar, self).__init__(model, color, mpg) 

car = ElectricCar('battery', 'ford', 'golden', 10) 
print car.__dict__ 

下面是輸出:

{'color': 'golden', 'mpg': 10, 'model': 'ford', 'battery_type': 'battery'}