How can a child class inherit a class method from its parent that gets a class variable from the child in python?
Question:
I have a code here where I define a parent class with class methods and class variables:
class Parent:
var1 = 'foo'
var2 = 'bar'
def getVar1Var2AsString(self):
return f'{Parent.getVar1()}_{Parent.getVar2()}'
@classmethod
def getVar1(cls):
return cls.var1
@classmethod
def getVar2(cls):
return cls.var2
And then, I have a code where I define the child class:
class Child(Parent):
var1 = 'banana'
var2 = 'apple'
And then I run:
child = Child()
output = child.getVar1Var2AsString()
print(output)
I expected that the output would return banana_apple
, but it returns foo_bar
instead.
How can I get the result I expect? I’m kind of new in OOP.
Answers:
In getVar1Var2AsString
, when you call Parent.getVar1()
, you do so without any reference to the current object or its class. It always looks up the methods on Parent
. If you want to look up the methods in the current object’s class, use self.getVar1()
. You also don’t need the getter methods at all, you can just use self.var1
and self.var2
.
The inheritance is fine, it’s the variable access that’s wrong. In getVar1Var2AsString
, when you write Parent
, that always refers to Parent
(of course), not the class of self
, which can be got with type(self)
. Or if you’d rather look up the class variables on the instance, just use self
.
By the way, I don’t think the getters add anything here.
So:
def getVar1Var2AsString(self):
return f'{type(self).var1}_{type(self).var2}'
Or, since self
is only being used to look up its class, you could make it a class method:
@classmethod
def getVar1Var2AsString(cls):
return f'{cls.var1}_{cls.var2}'
To be clear, it looks like you thought cls
in a classmethod
would take the value of type(self)
, but that’s not the case.
In case you want to get foo_bar
in case the object is an instance of the Parent
class and banana_apple
in case it’s an instance of the Child
class you can do this by changing your getVar1Var2AsString
to
@classmethod
def getVar1Var2AsString(cls):
return f"{cls.getVar1()}_{cls.getVar2()}"
This way the values of the corresponding class are used to generate the output.
I have a code here where I define a parent class with class methods and class variables:
class Parent:
var1 = 'foo'
var2 = 'bar'
def getVar1Var2AsString(self):
return f'{Parent.getVar1()}_{Parent.getVar2()}'
@classmethod
def getVar1(cls):
return cls.var1
@classmethod
def getVar2(cls):
return cls.var2
And then, I have a code where I define the child class:
class Child(Parent):
var1 = 'banana'
var2 = 'apple'
And then I run:
child = Child()
output = child.getVar1Var2AsString()
print(output)
I expected that the output would return banana_apple
, but it returns foo_bar
instead.
How can I get the result I expect? I’m kind of new in OOP.
In getVar1Var2AsString
, when you call Parent.getVar1()
, you do so without any reference to the current object or its class. It always looks up the methods on Parent
. If you want to look up the methods in the current object’s class, use self.getVar1()
. You also don’t need the getter methods at all, you can just use self.var1
and self.var2
.
The inheritance is fine, it’s the variable access that’s wrong. In getVar1Var2AsString
, when you write Parent
, that always refers to Parent
(of course), not the class of self
, which can be got with type(self)
. Or if you’d rather look up the class variables on the instance, just use self
.
By the way, I don’t think the getters add anything here.
So:
def getVar1Var2AsString(self):
return f'{type(self).var1}_{type(self).var2}'
Or, since self
is only being used to look up its class, you could make it a class method:
@classmethod
def getVar1Var2AsString(cls):
return f'{cls.var1}_{cls.var2}'
To be clear, it looks like you thought cls
in a classmethod
would take the value of type(self)
, but that’s not the case.
In case you want to get foo_bar
in case the object is an instance of the Parent
class and banana_apple
in case it’s an instance of the Child
class you can do this by changing your getVar1Var2AsString
to
@classmethod
def getVar1Var2AsString(cls):
return f"{cls.getVar1()}_{cls.getVar2()}"
This way the values of the corresponding class are used to generate the output.