【发布时间】:2015-10-06 01:54:14
【问题描述】:
我正在尝试编写装饰器来完成不同的工作,具体取决于它是装饰方法还是函数。
我尝试过这样的事情:
def dec(f):
def wrapper(*v, **kv):
if '__class__' in dir(f):
text = "Its a method"
else:
text = "Its a function"
print(text)
return f(*v, **kv)
return wrapper
class A:
@dec
def f(self):
pass
@dec
def f():
pass
a = A()
a.f()
f()
返回:
Its a method
Its a method
但这不起作用,因为所有函数也都有__class__ 属性:) 我也尝试在 A.f 上执行inspect.ismethod,但 A.f 就像函数一样被对待,但在 A 命名空间中,它当然返回 false。如果我们完成了inspect.ismmethod(a.f),它将返回True,其中a 是A 的实例,但我等不及要实例了。
【问题讨论】:
-
在装修时,你所拥有的只是一个功能。只有当查找名称是一个绑定到实例的函数并且你得到一个方法。
-
换句话说,您可以将任何旧函数粘贴到一个类上,它将作为一个方法工作。在类加载时,类定义中没有任何内容使函数成为方法。
-
函数上的
__class__属性与您在其上定义的自定义类无关。 -
因此,您无法检测到您是否在包装函数或方法。你为什么需要这个?您唯一可以确定的是,方法将有一个实例作为第一个参数传入。是的,这意味着您可以手动获取任何函数并传入实例,而您无法检测到差异。
-
查看this答案
标签: python python-3.x