6

I've decorated a method in Python. And when I import the module that contains the method, the decorator autoruns.

I realize that this is how decorators were made however Is there a way to have decorators NOT do this?

4

3 回答 3

4

听起来您想要做的是选择在运行时应用什么装饰器。像这样的东西可能会起作用:

to_decorate = []

def decorate_later(func):
    to_decorate.append(func)
    return func

@decorate_later
def do_stuff(*args, **kw):
    print('I am doing stuff')
@decorate_later
def do_more_stuff(*args, **kw):
    print('Even more stuff')

def apply_decorator(decorator):
    for func in to_decorate:
        globals()[func.func_name] = decorator(func)

然后您可以导入模块,所有功能都将正常定义。 decorate_later返回未修改的原始函数。您可以调用apply_decorator()以将指定的装饰器应用于模块中注册的所有函数@decorate_later

于 2013-10-26T02:03:50.930 回答
3

这正是venusian图书馆所做的;您根据其 API 定义您的装饰器,但在您对包含的模块或包进行“扫描”之前,不会触发实际行为。

你甚至不需要一个全局的 app 对象来使用 venusian 装饰器;您可以将 app 对象作为扫描的一部分传入,它会传递给装饰器实现。因此,例如,只需一个装饰器,就可以在多个所有者之间共享相同的功能,只需进行多次扫描即可。

这就是 Pyramid Web 框架用于事件注册的内容,因此仅导入模块并不需要应用程序实例。一个很好的例子是他们的事件订阅者

于 2013-10-26T02:19:25.603 回答
1

利用

 if __name__ == "__main__":
    #code

在文件中,其中代码都在方法或类之外(在导入时运行)。

于 2013-10-26T00:35:29.893 回答