【发布时间】:2019-01-03 15:22:09
【问题描述】:
将类的方法包装在“样板”Python 装饰器中会将该方法视为常规函数,并使其失去引用类实例对象的__self__ 属性。这可以避免吗?
参加以下课程:
class MyClass(object):
def __init__(self, a=1, b=2):
self.a = a
self.b = b
def meth(self):
pass
如果meth() 未修饰,MyClass().meth.__self__ 指的是实例方法并启用类似setattr(my_class_object.meth.__self__, 'a', 5) 的东西。
但是当在装饰器中包装任何东西时,只传递函数对象;它实际绑定的对象不会随它一起传递。 (见this答案。)
import functools
def decorate(method):
@functools.wraps(method)
def wrapper(*args, **kwargs):
# Do something to method.__self__ such as setattr
print(hasattr(method, '__self__'))
result = method(*args, **kwargs)
return result
return wrapper
class MyClass(object):
def __init__(self, a=1, b=2):
self.a = a
self.b = b
@decorate
def meth(self):
pass
MyClass().meth()
# False <--------
这可以被覆盖吗?
【问题讨论】:
-
这对我来说似乎是一个 XY 问题。为什么要访问
__self__属性?为什么不直接添加self作为wrapper的第一个参数? -
为什么你不能做
setattr(args[0], 'a', 5)?args[0]on 方法是self -
@Aran-Fey 我怀疑有人会这么说......一个例子:使用装饰器更新一个类属性,该属性是方法调用及其参数的日志。
-
@AndrejKesely 啊,呃。我认为这应该在这里工作
-
真的有意义吗?使用
args[0]而不是def wrapper(self, *args, **kwargs):?有什么区别?
标签: python python-3.x python-decorators