2012-10-11 64 views
2

我有一个python module_A这是做这样的事情:Python的钩子模块初始化

myvar = "Hello" 

def message(): 
    print myvar 

从另一个模块,我要导入的功能message

from module_A import message 

但这定义myvar,我不想要(因为这里没有真正相关的原因)。我想我需要的是区分导入东西从一个模块和使用任何导入的符号。当我使用message时,我实际上只想要myvar初始化

我有任何类型的python钩子,我可以用来初始化的东西,每当一个函数或类被访问?我想类似以下的东西:像这样的

module_setup_done = False 
def setup(): 
    global module_setup_done, myvar 
    if not module_setup_done: 
     myvar = "Hello" 
     module_setup_done = True 

def message(): 
    setup() 
    print myvar 

但是,以减少混乱,我想这是自动调用的东西:

def _init_module(): 
    global myvar 
    myvar = "Hello" 

def message(): 
    print myvar 

_init_module()将被称为唯一一次,并且只有第一次在模块中的东西是访问,而不是什么时候是导入

在python中是否支持这种模式?

回答

4

不,没有内置的支持。如果你想单独初始化导入模块的东西,写一个函数来完成初始化,然后当你想初始化这些东西时调用函数。如果你想在其他事情被调用时“自动”初始化事物,你必须用你已经发布的代码自己处理代码。

但是,如果你发现自己这样做,你可能会做一些不合理的事情。你不会详细说明你为什么要这样做,但总的来说,这种隐式初始化在Python中并不是一个好习惯。当你明确地告诉它们是,例如通过导入一个模块或者调用某种初始化函数时,事物被初始化。为什么你觉得有必要进行这种单独的,隐式的初始化步骤?

+0

我会尽量总结一下:我的全局变量实际上是一个芹菜模块中的缓存线程,在这个模块中定义了一些芹菜任务。我有一个这个芹菜模块的客户端,它必须导入芹菜任务,但并不真正执行任务(它只会通过芹菜进行代理)。关键是,当我在对客户端进行单元测试时,因为它正在从celery模块导入符号,所以缓存线程将被初始化并启动,即使客户端中完全不需要这些符号。由于这个超线程,单元测试并没有结束。 – dangonfast

+0

在这种情况下,更简单的解决方案可能是根据是否运行测试,使用myvar的if/else。大概有一些方法可以区分正常执行和单元测试执行,然后你可以这样做: myvar = caching_thread if in_test_mode else否 –

+0

是的,我会做类似于Jeremy Lewis的建议。你真正想要做的是以某种方式标记测试用法,并在这种情况下以不同的方式做事。一种方法就是像我描述的那样有一个初始化函数,而不是在测试期间调用它。那么你不得不手动调用它来进行非测试使用,但这并没有那么糟糕。 – BrenBarn