我知道@ 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版本中被更改(更正?).
谢谢.
考虑到:
>>> 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.
| 归档时间: |
|
| 查看次数: |
855 次 |
| 最近记录: |