I have the following class hierarchy:
class A(object):
def __init__(self, filename, x):
self.x = x
# initialize A from filename
# rest of A's methods
class B(A):
def __init__(self, filename):
super(B, self).__init__(filename, 10)
# rest of B's methods
Both classes are passed the name of a file in their __init__ methods. The file contents are then used to initialize some data in the objects.
To facilitate testing I’d like to be able to construct an A or B instance by passing it the data directly, rather than having the object read from a file. I thought that a pair of factory functions, each implemented using a classmethod might work, but I’ve been unable to get the versions in B to work at all. Here’s what I have so far:
class A(object):
def __init__(self, x):
self.x = x
@classmethod
def construct(cls, filename, x):
a = cls(x)
# initialize a from filename
return a
@classmethod
def test_construct(cls, data, x):
a = cls(x)
# initialize a from data
return a
class B(A):
def __init__(self):
super(B, self).__init__(10)
@classmethod
def construct(cls, filename):
# should construct B from filename
@classmethod
def test_construct(cls, data):
# should construct B from data
For the class methods in B to call their superclass class methods, you just use
super()as though you were calling an instance in a base class:Edit:
As you point out in your comment, there is then a problem because you’ve added an argument to the base class constructor. You should avoid making incompatible changes in method signatures between base and sub-classes: a
Binstance is anAinstance so it should accept any method call you can make to theAinstance.One option:
and now it works again, but you have to trust yourself not to pass ‘x’ to directly constructed instances of
B. Probably better would be to lose thexentirely from__init__which it looks like you could do by making it a class attribute or by setting it separately after construction.