gpt4 book ai didi

python - 如何动态装饰类方法,同时又不失去方法绑定(bind)状态?

转载 作者:太空宇宙 更新时间:2023-11-03 10:50:26 24 4
gpt4 key购买 nike

假设我有一个这样的装饰器:

def repeat(repeat_count):
def decorator(func):
def wrapped(self):
for X in range(repeat_count):
func() # Do Function
return wrapped
return decorator

和这样的类

class SomeClass(object):
def __init__(self, do_count):
self.some_method = repeat(do_count)(self.some_method)

def some_method(self):
print("I'm Doing Something")

因为装饰器只返回一个方法,所以很明显这是可行的。然而,它从类实例中解除了 some_method 函数的绑定(bind),所以我不能再做类似的事情:

>>> sc = SomeClass(10)
>>> sc.some_method()
# TypeError: wrapped() missing 1 required positional argument: 'self'

我得到一个异常,因为 self 不再自动传递。为了完成这项工作,我可以简单地这样做:

sc.some_method(sc)

但我宁愿不这样做。有什么方法可以将方法重新绑定(bind)到实例,最好不需要任何额外的导入(如 TypeMethod)就可以完成。

最佳答案

I get an exception because self is no longer automatically passed.

其实还是自动通过。你得到这个异常是因为你定义装饰器的方式要求它被传递两次。

在 wrapped 的运行时内,func 已经被绑定(bind)(即它已经 self 传递)。通过定义 wrapped 接受一个位置参数,您需要再次传入 self,这就是 sc.some_method(sc) 起作用的原因正确。 self 根据需要传递两次 - 一次隐式传递,一次显式传递。

对代码的最小修复是从 wrapped 的签名中删除 self,因为它已经根据 绑定(bind)中的描述符协议(protocol)隐式传递>self.some_method

def repeat(repeat_count):
def decorator(func):
def wrapped():
for X in range(repeat_count):
func() # Do Function
return wrapped
return decorator

然而,这并不是最好的解决方案。您需要接受 *args**kwargs 以便无论装饰函数的签名如何都可以应用您的装饰器:

def repeat(repeat_count):  # <-- the "decorator maker"
def decorator(func): # <-- the decorator
def wrapped(*args, **kwargs): # <-- this will replace "func"
for X in range(repeat_count):
func(*args, **kwargs) # <-- note: pass along the arguments!
return wrapped # <-- note: no call here!
return decorator

关于python - 如何动态装饰类方法,同时又不失去方法绑定(bind)状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51562280/

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