2010-05-21 102 views
1

我希望能夠從導入類調用全局函數,例如Python如何製作跨模塊功能?

在文件PetStore.py

class AnimalSound(object): 
    def __init__(self): 
     if 'makenoise' in globals(): 
     self.makenoise = globals()['makenoise'] 
     else: 
     self.makenoise = lambda: 'meow' 

    def __str__(self): 
     return self.makenoise() 

然後當我在Python解釋器

>>> def makenoise(): 
... return 'bark' 
... 
>>> from PetStore import AnimalSound 
>>> sound = AnimalSound() 
>>> sound.makenoise() 
'meow' 

測試我得到'喵'而不是'樹皮'。我嘗試過使用python-how-to-make-a-cross-module-variable中提供的解決方案,但沒有運氣。

回答

5

globals()調用返回,其中該呼叫是詞法位於模塊的全局;在Python中沒有內在的「動態範圍」 - 它在詞彙範圍內,就像幾乎所有現代語言一樣。

固體,正確的方式來獲得你的願望是要明確地傳遞給AnimalSound可調用它應該使用「製造噪音」的初始化的效果:即類應該是

class AnimalSound(object): 
    def __init__(self, makenoise=lambda: 'meow'): 
     self.makenoise = makenoise 

    def __str__(self): 
     return self.makenoise() 

和通話應該是

sound = AnimalSound(makenoise) 

有可行的,但不太完善的解決方案,如呼叫者通過自己的globals()(但不必要限制了可調用的名字!),甚至(顫慄)通過隱蔽渠道溝通裏對其他答案提倡者(如果在兩個單獨的模塊中根據相同的原理構建了AnimalSound兩個實例等,則這將是潛在的災難)。但是,「明確比隱含更好」,清潔,安全,公開的溝通導致了清潔,安全,可靠的系統架構:我懇切地建議您選擇這條路線。

+0

謝謝!我對誰給出接受的答案有點衝突,但我想我會接受你的建議並明確地通過該函數。 – Evan 2010-05-25 03:55:00

+0

@Evan,當然 - 我不喜歡@伊格納西奧建議通過隱蔽渠道進行溝通,但是我認爲它看起來更簡單(直到最初幾次你發現自己在浪費數小時或數天的時間來調試這種「簡單外觀」解決方案的災難性後果,這可能需要幾年或幾十年的經驗)。當然,如果你接受錯誤的解決方案,但是實施正確的解決方案,你將永遠不會得到真正理解爲什麼正確的解決方案是正確的;-)所需的痛苦體驗。 – 2010-05-25 03:59:11

2

Python中的「Global」範圍是Module範圍。

import PetStore 

PetStore.makenoise = makenoise