首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Python中使用装饰器动态创建方法

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

Stack Overflow用户
提问于 2012-09-12 06:00:57
回答 1查看 245关注 0票数 3

这很难。我不仅希望动态创建方法,还希望将装饰器与它们关联起来。这就是我尝试过的

代码语言:javascript
运行
复制
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()

输出为:

代码语言:javascript
运行
复制
    I am here
    I am here
    in dynamo 0
    in dynamo 1

预期输出:

代码语言:javascript
运行
复制
    I am here
    in dynamo 0
    I am here
    in dynamo 1

请解释为什么会发生这种情况,以及如何才能获得预期的结果?

EN

回答 1

Stack Overflow用户

发布于 2012-09-12 06:17:31

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

代码语言:javascript
运行
复制
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

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

代码语言:javascript
运行
复制
def func():
    pass
func = deco(func)

等同于

代码语言:javascript
运行
复制
@deco
def func():
    pass

无论采用哪种方法,最终都会得到本地名称空间中的func标签,该标签引用从将显式定义的func传递给deco时返回的对象。装饰器语法捆绑了一些额外的检查(比如确保deco的输入和输出总是可调用的),但基本上,如果某些东西在示例1中以给定的方式工作,那么它在示例2中就会以这种方式工作。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12378564

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档