【问题标题】:Decorating a Python method already decorated with @classmethod which calls another @classmethod装饰一个已经用 @classmethod 装饰的 Python 方法,该方法调用另一个 @classmethod
【发布时间】:2016-03-17 19:23:04
【问题描述】:

这是一个基本的 Python 问题。我正在尝试用我自己的装饰器my_decorator 来装饰@classmethod。原来的@classmethod实际上在里面调用了另一个@classmethod。调用此内部方法时会出现问题,因为它取决于cls 参数。如果我的类总是Foo,我可以用Foo.boo() 替换任何像cls.boo() 这样的调用会很好,但是当我编写从Foo 继承的子类时,这显然不是一个选择。下面是我要写的。

def my_decorator(method):
    def redefined_method(*args, **kwargs):
        print('Starting decorator')
        result = method(args, **kwargs)
        return result
    return redefined_method

class Foo(object):        
    @classmethod
    def boo(cls):
        print('Running from Foo\'s boo')

    @classmethod
    @my_decorator
    def bar(cls):
        print('Running from Foo\'s bar')
        '''
        Replacing the following line with 'Foo.boo()'
        produces no errors when calling `Foo.bar()`, 
        but then we can't run Child's version of the boo method.
        ''' 
        cls.boo()

class Child(Foo):
    @classmethod
    def boo(cls):
        print('Running from Child\'s version of boo')

if __name__ == '__main__':
    Foo.bar()    
    Child.bar()

我希望得到以下输出。

Starting decorator
Running from Foo's bar
Running from Foo\'s boo
Starting decorator
Running from Foo's bar
Running from Child\'s version of boo

电流输出。

Starting decorator
Running from Foo's bar
Traceback (most recent call last):
  File "C:\....\dec_example.py", line 29, in <module>
    Foo.bar()    
  File "C:\....\dec_example.py", line 4, in redefined_method
    method(args, **kwargs)
  File "C:\....\dec_example.py", line 21, in bar
    cls.boo()
AttributeError: 'tuple' object has no attribute 'boo'

我尝试切换@classmethod@my_decorator 的顺序,但它仍然不起作用并产生以下堆栈跟踪。

Starting decorator
Traceback (most recent call last):
  File "C:\....\dec_example.py", line 29, in <module>
    Foo.bar()    
  File "C:\....\dec_example.py", line 4, in redefined_method
    method(args, **kwargs)
TypeError: 'classmethod' object is not callable

【问题讨论】:

    标签: python oop python-3.x decorator python-decorators


    【解决方案1】:

    你忘了解压args

    def my_decorator(method):
        def redefined_method(*args, **kwargs):
            print('Starting decorator')
            method(args, **kwargs)
            # here ^, no star!
        return redefined_method
    

    【讨论】:

    • 通常你也会返回 method 返回的值。在这个版本中,没有返回值是可能的。
    • @TomKarzes,哎呀,这是一个错字。不错的收获。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-30
    • 2017-04-17
    • 2021-12-26
    • 1970-01-01
    • 2021-10-23
    • 2019-11-08
    • 2019-08-08
    相关资源
    最近更新 更多