gpt4 book ai didi

python - 在 Python 中使用装饰器创建动态方法

转载 作者:太空宇宙 更新时间:2023-11-03 14:30:14 25 4
gpt4 key购买 nike

这很难。我不仅想动态创建方法,还想将装饰器与它们相关联。这是我试过的

import inspect
import types

class Dynamo(object):
pass

def call_me_dec(func):
print 'I am here'
return func

def add_dynamo(cls,i):
# @call_me_dec
def innerdynamo(self):
print "in dynamo %d" % i
return i

innerdynamo.__doc__ = "docstring for dynamo%d" % i
innerdynamo.__name__ = "dynamo%d" % i
setattr(cls, innerdynamo.__name__, innerdynamo)

def add_decorators(cls):
for name, fn in inspect.getmembers(cls):
if isinstance(fn, types.UnboundMethodType):
setattr(cls, name, call_me_dec(fn))

for i in range(2):
add_dynamo(Dynamo, i)

add_decorators(Dynamo)

d=Dynamo()
d.dynamo0()
d.dynamo1()

输出是:

    I am here
I am here
in dynamo 0
in dynamo 1

预期输出:

    I am here
in dynamo 0
I am here
in dynamo 1

请解释为什么会这样,我怎样才能得到想要的结果?

最佳答案

您会看到,因为装饰器代码是在创建装饰函数时调用的,而不是在调用函数时调用的。如果你想让代码在调用时运行,你需要让装饰器返回一个调用装饰方法的可调用对象(通常是闭包)。例如:

def call_me_dec(func):
print 'Decorating %s' % func
def func_wrapper(*args, **kwargs):
print 'Calling %s' % func
return func(*args, **kwargs)
return func_wrapper

装饰器语法只是语法糖。记住:

def func():
pass
func = deco(func)

相当于

@deco
def func():
pass

无论哪种方式,您最终都会在本地 namespace 中使用 func 标签引用通过 func 返回的对象,如明确定义给 deco。 Decorator 语法捆绑了一些额外的检查(比如确保 deco 的输入和输出始终是可调用的),但基本上,如果某些东西在示例 1 中以给定的方式工作,那么它在示例 1 中也将以这种方式工作示例 2。

关于python - 在 Python 中使用装饰器创建动态方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12378564/

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