Question

I am looking for a way to access a subclasses variables from the parent class which is instantiated in a different file. For example

basefile.py:

class A(object): #gets subclassed
    var = 0 #place holder

    def printTheVar(self):
        print self.var


class B(object):
    def buildAndCallA(self):
        a = A()
        a.printTheVar()

implementationfile.py:

from basefile import *

class A(A):
    var = 10

if __name__ == '__main__':
    b = B()
    b.buildAndCallA()

When I run:

$ python implementationfile.py

I get 0. I want to get 10

When both parent class and implementation class are in the same file, this is obviously not a problem but I have a project structure which requires they not be:

somedir/
| basefile.py
| implementations/
| -- implementationA.py
| -- implementationB.py
| -- implementationC.py

I think that the abc module might help but my experiments with that have proven fruitless so far.

Was it helpful?

Solution 2

@James's answer got me most of the ways there. Here is a more global way to do it using three files for clarity (which is really how the project is organized anyways)

script.py:

if __name__ == '__main__':
    if sys.argv[0] == 'useImplementation1'
        import implementations.implementation1 as implementation
    elif sys.argv[1] == 'useImplementation2':
        import implementations.implementation2 as implementation

    b = implementation.B(cls=implementation)
    b.buildAndCallA()

basefile.py (notice the A = cls.A this is the key):

class A(object):
    var = 0 #place holder

    def printTheVar(self):
        print self.var


class B(object):
    def __init__(self,cls):
        global A
        A = cls.A

    def buildAndCallA(self):
        a = A()
        a.printTheVar()

implementation1.py:

from basefile import *

class A(A):
    var = 10

OTHER TIPS

I'd suggest, if possible, you pass the class you want to use to the buildAndCallA method. So it should look something like this:

def buildAndCallA(self,cls):
    a = cls()
    a.printTheVar()

And then you can call it like this:

b.buildAndCallA(A)

Then it will use whatever version of the A class is in scope at the time it is called.

You could even set it up with a default parameter, so it will use the version of A in the base file by default, but you can still override it when necessary.

def buildAndCallA(self,cls=A):
    a = cls()
    a.printTheVar()

Then if you call b.buildAndCallA() with no parameter, it will construct an instance of the A class from the base file.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top