2

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:

Using super() in nested classes

3
  • 2
    super(self.__class__, self).__init__ ... should be enough. The result of super is already Reference Commented Feb 5, 2016 at 5:01
  • 2
    No, never pass self.__class__ to super(). It will misbehave badly if you ever subclass that class. Commented Feb 5, 2016 at 5:04
  • Have you tried this `super(TransMap, self).__init__(#your arg) Commented Feb 5, 2016 at 5:05

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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

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

will call the __init__ method of parent class.

2 Comments

Don't do that. It misbehaves if you subclass the current class. The first argument to super() should (almost) always be an import-time constant, not something you figure out by inspecting self.
@Kevin, yes i understand that, sorry i didn't mean that way, and yes there are other drawbacks too, of using it, and yes the best way to use directly super().__init__(...) but still thanks for making me correct

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.