2011-04-27 134 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中刪除,以便實際上在下一次重新加載進口。