gpt4 book ai didi

python - 实例方法的装饰器

转载 作者:行者123 更新时间:2023-11-28 20:33:00 24 4
gpt4 key购买 nike

在“样板”Python 装饰器中包装一个类的方法会将该方法视为常规函数,并使其失去引用类实例对象的 __self__ 属性。这可以避免吗?

参加以下类(class):

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).

但是当在装饰器中包装任何东西时,只有函数对象被传递;它实际绑定(bind)到的对象不会与其一起传递。 (参见 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 <--------

这可以被覆盖吗?

最佳答案

您在这里的主要误解是操作顺序。

decorate() 装饰器被调用时,meth() 还不是方法 - 它仍然是一个函数 - 只有当 class block 结束了 meth 被元类描述符转换为方法! - 这就是它还没有 __self__ 的原因。

换句话说,要装饰方法,您必须忽略它们是方法这一事实并将它们视为普通函数 - 因为当装饰器被调用时它们就是这样。

事实上,原始的 meth 函数永远不会变成方法 - 相反,您从装饰器返回的函数 wrapper 将成为类的一部分,并将成为稍后将获得 __self__ 属性的一个。

关于python - 实例方法的装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51542063/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com