简体   繁体   English

python子类方法调用用非类方法覆盖的类方法

[英]python child class method calling overridden classmethod with non-classmethod

I am trying to do the following in python3:我正在尝试在 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.即便如此child.show按预期工作。 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:所以似乎child.ask正在调用Parent.show ...我也尝试将Child.show标记为 classmethod,但是cls.name没有显示预期的输出:

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?有没有办法用非类方法覆盖父类方法,但保留其他父类方法来调用被覆盖的方法?

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当您even so child.show works as expected. So it seems that child.ask is calling Parent.show even so child.show works as expected. So it seems that child.ask is calling Parent.show , thats not what is happening. even so child.show works as expected. So it seems that child.ask is calling Parent.show ,这不是正在发生的事情。

When you called instance.ask("what") , it called the @classmethod decorated method of the Child class (which is inherited from the parent).当您调用instance.ask("what")时,它调用了Child类的 @classmethod 装饰方法(从父类继承)。 This ask method is passing the class Child as the first argument, (not the instance you created).这个ask方法将类Child作为第一个参数(不是您创建的实例)传递。 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}???' Child类中的 show 方法是一个实例方法,并期望第一个参数是实际实例( self ),但字符串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希望这有帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM