I am trying to do the following in python3:
class Parent:
@classmethod
def show(cls, message):
print(f'{message}')
@classmethod
def ask(cls, message):
cls.show(f'{message}???')
class Child(Parent):
@property
def name(self):
return 'John'
def show(self, message):
print(f'{self.name}: {message}')
instance = Child()
instance.ask('what')
But it then complains
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 7, in ask
TypeError: Child.show() missing 1 required positional argument: 'message'
even so child.show
works as expected. So it seems that child.ask
is calling Parent.show
... I tried to mark Child.show
as classmethod too, but then the cls.name
is not showing the expected output:
class Child2(Parent):
@property
def name(self):
return 'John'
@classmethod
def show(cls, message):
print(f'{cls.name}: {message}')
instance2 = Child2()
instance2.ask('what')
this shows
<property object at 0xfc7b90>: what???
Is there a way to override a parent classmethod with a non-classmethod, but keeping other parent classmethod to call the overridden one?
CodePudding user response:
I found it hard to follow for the second half of the question but there was an issue I saw and it might help you solve your problem.
When you said even so child.show works as expected. So it seems that child.ask is calling Parent.show
, thats not what is happening.
When you called instance.ask("what")
, it called the @classmethod decorated method of the Child
class (which is inherited from the parent). This ask
method is passing the class Child
as the first argument, (not the instance you created). This means the line
cls.show(f'{message}???')
is equivalent to
Child.show(f'{message}???') # because cls is the Class not the instance
The show method inside the Child
class is an instance method and expects the first argument to be the actual instance (self
) but the string f'{message}???'
is being passed to it and it expects a second message string to be passed so that's why its is throwing an error.
Hope this helped