简体   繁体   English

如何在导入时不运行Python Decorator

[英]How to make Python Decorator NOT run when imported

I've decorated a method in Python. 我在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? 我意识到这就是装饰器是如何制作的,但有没有办法让装饰者不这样做?

It sounds like what you want to do is to choose what decorator to apply at run time. 听起来你想要做的是选择在运行时应用什么装饰器。 Something like this might work: 像这样的东西可能会起作用:

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)

Then you can import the module and all the functions will be defined as normal. 然后您可以导入模块,所有功能都将被定义为正常。 decorate_later returns the original function unmodified. decorate_later返回未修改的原始函数。 You can call apply_decorator() to apply a specified decorator to all of the functions in the module that were registered by @decorate_later 您可以调用apply_decorator()将指定的装饰器应用于模块中由@decorate_later注册的所有@decorate_later

This is exactly what the venusian library does; 这正是venusian图书馆的作用; you define your decorators according to their API, but the actual behavior isn't triggered until you do a "scan" of the containing module or package. 您可以根据API定义装饰器,但在对包含的模块或包进行“扫描”之前,不会触发实际行为。

You don't even need to have a global app object to use venusian decorators; 您甚至不需要使用全局应用程序对象来使用venusian装饰器; you can pass in the app object as part of the scan, and it'll get passed along to the decorator implementations. 您可以将应用程序对象作为扫描的一部分传入,它将被传递给装饰器实现。 So, for example, the same functions can be shared among multiple owners with only a single decorator, just by doing more than one scan. 因此,例如,只需要一个装饰器就可以在多个所有者之间共享相同的功能,只需执行多次扫描即可。

This is what the Pyramid web framework uses for eg event registration, so that merely importing a module doesn't expect to need an app instance. 这就是Pyramid Web框架用于例如事件注册的内容,因此仅导入模块不需要app实例。 A good example is their event subscriber . 一个很好的例子是他们的活动订户

Use 使用

 if __name__ == "__main__":
    #code

in the file, where code is all outside a method or class ( that runs when you import it). 在文件中,代码全部在方法或类之外(在导入时运行)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM