How do I use the python-decorator package to decorate classmethods?

别来无恙 提交于 2019-12-06 08:44:25

问题


I'm have a decorator that I want to use to decorate class methods. In the following example, the @mydec decorator works fine on its own, however it does not preserve the function signature when using help() or pydoc. In order to fix this, I looked at using @decorator python-decorator package:

import functools
import decorator


@decorator.decorator
def mydec(func):
    @functools.wraps(func)
    def inner(cls, *args, **kwargs):
        # do some stuff
        return func(cls, *args, **kwargs)
    return inner


class Foo(object):
    @classmethod
    @mydec
    def bar(cls, baz='test', qux=None):
        print (baz, qux)


Foo.bar()

Unfortunately, this results in the following exception:

Traceback (most recent call last):
  File "/tmp/test.py", line 21, in <module>
    Foo.bar()
  File "<string>", line 2, in bar
TypeError: mydec() takes exactly 1 argument (4 given)

回答1:


You do not need to provide your own wrapper anymore, just use @decorator.decorator on the inner function, which takes one extra first positional argument, the function wrapped:

@decorator.decorator
def mydec(func, cls, *args, **kwargs):
    # do some stuff
    return func(cls, *args, **kwargs)

The decorator package doesn't use a closure for decorators and instead passes in the wrapped function as an argument.

Demo:

>>> @decorator.decorator
... def mydec(func, cls, *args, **kwargs):
...     # do some stuff
...     return func(cls, *args, **kwargs)
... 
>>> class Foo(object):
...     @classmethod
...     @mydec
...     def bar(cls, baz='test', qux=None):
...         print (baz, qux)
... 
>>> Foo.bar()
('test', None)


来源:https://stackoverflow.com/questions/18577069/how-do-i-use-the-python-decorator-package-to-decorate-classmethods

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!