Reputation: 403
I have a python class that serves as a baseclass for further subclasses. It contains a methods that should act on all subclass the same, e.g. I want to put it in the base class. The problem is, that this method should return a new instance of the subclass. But I since the baseclass is located before the definition of the subclass, I can not create a new instance of the subclass, as it is not known in the scope of the baseclass:
class Base:
def __init__(self, value):
self.value = value
def convert_child_classes(self, newclass):
newvalue = MakeUsableInNewclass(self.value)
newattr = MakeUsableInNewclass(self.subclassattr)
return newclass(newattr, newvalue)
class Child1(Base):
def __init__(self, subclassattr, value)
super(Child, self).__init__(value)
self.subclassattr = subclassattr
def MethodForSubClassAttr(self):
...do sth with self.subclassattr...
class Child2(Base):
def __init__(self, subclassattr, value)
super(Child, self).__init__(value)
self.subclassattr = subclassattr
def SomeOtherSubClassAttrMethod(self):
...do sth that is related to this class attr...
I if I have an instance of Child1 I want to be able to do some stuff with its data and then return an instance of the Child2 with the new values when calling convert_child_classes(Child2):
A = Child1('someattr', 5)
B = A.convert_child_classes(Child2)
now B should be an instance of Child2 with a value that was calculated form Child1. But since Base class does now know what Child1 or Child2 is, it can not initiate the new class.
Upvotes: 0
Views: 444
Reputation: 1424
I got your problem:
1. Actually you're using Child
in the super
and it's wrong, as it should be the name of the class you're operating on, in this case Child1
or Child2
.
2. I'd add Base as an abstract class, to ensure it won't be instantiated (as I got from your question it's the case).
3. since the method MakeUsableInNewClass
is mandatory to be implemented, I'd add as an abstractmethod
to ensure implementation on the Child ones.
So the correct code would be:
from abc import ABC, abstractmethod
class Base(ABC):
def __init__(self, value):
self.value = value
def convert_child_classes(self, newclass):
newvalue, newattr = self.MakeUsableInNewclass()
return newclass(newattr, newvalue)
@abstractmethod
def MakeUsableInNewclass(): pass
class Child1(Base):
def __init__(self, subclassattr, value):
super(Child1, self).__init__(value)
self.subclassattr = subclassattr
def MakeUsableInNewclass(self):
newvalue = self.value #do operations
newattr = self.subclassattr #do operations
return newvalue, newattr
class Child2(Base):
def __init__(self, subclassattr, value):
super(Child2, self).__init__(value)
self.subclassattr = subclassattr
def MakeUsableInNewclass(self):
newvalue = self.value #do operations
newattr = self.subclassattr #do operations
return newvalue, newattr
Upvotes: 1
Reputation: 55669
Something like this ought to work (untested):
class Measurement:
@classmethod
def from_other(cls, other):
base = other.convert_to_base_unit()
converted = cls.base_to_unit(base)
return cls(converted)
@classmethod
def base_to_unit(cls, value):
# Let the subclass implement this
raise NotImplementedError
def convert_to_base_unit(self):
# Let the subclass implement this
raise NotImplementedError
Implemented this way, the base class doesn't need to know anything about the subclasses. The base class provides the template method (from_other
) and the subclasses provide the implementation.
Upvotes: 1