如何检索原始@classmethod,@ stestmethod或@property

Dan*_*ure 3 python

我知道@ decorator.decorator不允许在@staticmethod,@ classmethod(也许还有@property)之上进行装饰.我理解用法:

class A(object):
    @classmethod
    @mydecorator
    def my_method(cls): pass
Run Code Online (Sandbox Code Playgroud)

但是,在调试模块中,我仍然想尝试动态地执行它.所以我想知道从那些描述符(?)中检索原始方法的方法是什么.我读过很少的回复,但我还是很困惑......

我看到一个类的示例,并检索:

class my_class(property):
    def __get__(self, obj, cls):
        return self.fget.__get__(None, cls)
Run Code Online (Sandbox Code Playgroud)

我喜欢装饰的签名保留,但仍然不知道如何做到这一点.我试图实现的逻辑是:

import decorator

def mydecorator(f, *d_args, **d_kwargs):
    if (isinstance(f, classmethod)):
        return classmethod(mydecorator(f.__get__.?WHATELSE?))
    elif (isinstance(f, staticmethod)):
        return staticmethod(mydecorator(f.__get__.?WHATELSE?))
    elif (isinstance(f, property)):
        return property(mydecorator(f.__get__.?WHATELSE?))
    else:
        return decorator.decorator(f)
Run Code Online (Sandbox Code Playgroud)

我试图在Python 2.6中这样做,所以我也欢迎指出@decorator在未来的python版本中被更改(更正?).

谢谢.

Odo*_*ois 8

考虑到:

>>> def original():pass

>>> classmethod(original).__func__ == original
True
>>> staticmethod(original).__func__ == original
True
>>> property(original).fget == original
True
Run Code Online (Sandbox Code Playgroud)

你的功能应该是这样的:

import decorator

def mydecorator(f, *d_args, **d_kwargs):
    if (isinstance(f, classmethod)):
        return classmethod(mydecorator(f.__func__))
    elif (isinstance(f, staticmethod)):
        return staticmethod(mydecorator(f.__func__))
    elif (isinstance(f, property)):
        return property(mydecorator(f.fget))
    else:
        return decorator.decorator(f)
Run Code Online (Sandbox Code Playgroud)

UPD:抱歉不注意.在2.*之前的2.7.,你应该做的事情如下:

import decorator
def mydecorator(f, *d_args, **d_kwargs):
    if (isinstance(f, classmethod)):
        return classmethod(mydecorator(f.__get__(True).im_func))
    elif (isinstance(f, staticmethod)):
        return staticmethod(mydecorator(f.__get__(True)))
    elif (isinstance(f, property)):
        return property(mydecorator(f.fget))
    else:
        return decorator.decorator(f)
Run Code Online (Sandbox Code Playgroud)

请注意,语句中的那些True对象f.__get__(True).im_func可以被除外的任何对象替换None.