I am confused on why the code below does not work:
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'
Attempting to instantiate leads to the error:
AttributeError: 'super' object has no attribute 'Reference'
I have tried different versions such as super(TransMap, self).Reference.__init__ and Reference.__init__, but all give different versions of a NameError. How is this different than the simple case outlined here:
3 Answers 3
You want this:
super(ComparativeAnnotatorConfiguration.TransMap, self).__init__(...)
This is a consequence of Python's class scoping rules: class variables are not in scope inside methods. This does not change just because your "variable" is itself a class. As far as Python is concerned, that's exactly the same thing.
In Python 3, you can write the far simpler:
super().__init__(...)
This is yet another reason to upgrade.
Comments
You could use 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)
Sample Inheritance and initializing parent constructor code :
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__
Here's the output:
{'color': 'golden', 'mpg': 10, 'model': 'ford', 'battery_type': 'battery'}
Comments
super(self.__class__, self).__init__()
will call the __init__ method of parent class.
2 Comments
super() should (almost) always be an import-time constant, not something you figure out by inspecting self.super().__init__(...) but still thanks for making me correct
super(self.__class__, self).__init__ ...should be enough. The result ofsuperis alreadyReferenceself.__class__tosuper(). It will misbehave badly if you ever subclass that class.