2011-04-27 155 views
0

我想导入模块,但导入的行为可能会有所不同,具体取决于我要施加的某些外部条件。有什么策略可以实现这个结果?导入模块并在导入时更改模块行为

示例。我想要一个模块foo.py.如果我import foo根据某些与模块无关的外部条件,我会得到“你好”或“再见”的打印,而取决于外部因素。一个微不足道的可能是一个全局变量,但我不认为python范围规则允许我从模块foo之外获取全局变量。

例子:

fop.py

import __main__ 
try: 
    __main__.bar 
    present = True 
except: 
    present = False 

if present: 
    print "present" 
else: 
    print "not present" 

现在,当我输入的模块,我可以得到不同的结果

Python 2.7.1 (r271:86832, Feb 27 2011, 20:04:04) 
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import foo 
not present 
>>> 

Python 2.7.1 (r271:86832, Feb 27 2011, 20:04:04) 
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> bar = 5 
>>> import foo 
present 

我知道这很奇怪,但我有一个非常,这是非常非常好的理由。

+2

听起来像没有人会明白的代码... – 2011-04-27 16:06:16

+0

塞巴斯蒂安:这是_exactly_我​​想要达到的效果 – 2011-04-27 16:06:42

+0

您可以举一个用例的例子吗?如外部条件的一个例子,什么构成“行为不同”? – samplebias 2011-04-27 16:10:51

回答

0

您实际上可以从模块内部访问主脚本的全局变量。

在主脚本:

a = 42 
import foo 

foo.py

import __main__ 
print __main__.a 

请注意,我只是说,这是可能的:)

+0

很好。其他方法实现相同? – 2011-04-27 16:36:19

0

的标准方式围绕数据传递有关的环境是(自然地)使用环境变量:

>>> import os 
>>> os.environ['PY_BAR'] = '1' 
>>> import foo 
"present" 

另一种可能的模式是执行自定义例程/钩子,以便导入foo时,可以在模块加载之后但返回控制权之前以静默方式执行下面提到的初始化例程。


扩展斯文的模式,你可以做foo模块的初始化明确,使得外部环境可以影响它。这产生了良好限定的,用于记录其用于前喷射状态进入foo模块接口:

定义foo.py模块:

# define all your classes and functions, then leave global stubs which will 
# be filled in by the module initialization function init(), which _must_ be 
# called before the module is used. 

_DATA = {} 

def use_data(): 
    # use '_DATA' to do something useful 
    ... 

def init(state): 
    # use 'state' to populate '_DATA' 
    ... 

定义脚本:

# main configures the state, passing it explicitly to foo 
state = {'variable': 42} 
import foo 
foo.init(state) 
foo.use_data() 
+0

不,不起作用。我想控制模块__at__导入,而不是之后。 – 2011-04-27 20:44:06

0

你可以使用virtual module像这样,你可以在某个地方定义你的模块,把你想要的东西放在里面,每次你导入i你会得到这个虚拟模块,而不是原来的模块。当外部条件改变时,你只需重做整个事情,并将其他东西放入模块中。

如果您针对不同的行为有不同的文件,那么如果条件更改,您还可以在其__init__.py中更改程序包的搜索路径,只需将其从sys.modules中删除,以便实际上在下一次重新加载进口。