2009-04-10 90 views
3

Python中是否有超級全局(如PHP)?我在整個項目中使用了獨立的文件,類和函數中的某些變量,我不想在每個文件中都聲明它。Python超全球?

+0

既然你不「聲明」任何東西,你的意思是「參考」或「導入」?你能澄清你在做什麼導致問題嗎? – 2009-04-10 01:57:38

回答

18

在理論上是的,你可以開始噴涌CRUD到__builtin__:

>>> import __builtin__ 
>>> __builtin__.rubbish= 3 
>>> rubbish 
3 

但是,不這樣做;這會給你的應用程序編程帶來可怕的惡果 - 癌症。

classes and functions and i don't want to have to keep declaring

將它們放入模塊中,當需要使用它們時將它們「導入」它們。

I have certain variables i want to use throughout my whole project

如果你必須有不合格的價值,只是把它們放在一個名爲類似「mypackage中/ constants.py」則:

from mypackage.constants import * 

如果他們真的是「變量」在您更改他們在應用程序執行期間,你需要開始將它們封裝在對象中。

+0

在mypackage.constants中使用`import *`幾乎和monkeypatching`__builtin__`一樣糟糕 - 它具有破壞命名空間使用的相同效果。正確的建議是你給的:「把它們放在模塊中,當你需要使用它們時,」導入「它們。」這不是我們應該靈活處理的一個問題,因爲它會傷害我們計劃的可讀性,靈活性,可預測性和明確性。 – 2011-02-04 13:31:22

+0

@Mike:通常從模塊導入nonmodulething`確實是非常不可取的,但對於符號常量的具體情況,我認爲這種情況可能是有爭議的。在每個用法中輸入「mypackage.constants.THINGTYPE_SOMETHING」的完整路徑太長。當然,還有其他可能更好的方法,但在這種情況下,潛在的危害會相當小。 – bobince 2011-02-05 11:29:08

4

即使有,你也不應該使用這樣的結構EVER。考慮使用borg模式來保存這種東西。

class Config: 
    """ 
    Borg singlton config object 
    """ 
    __we_are_one = {} 
    __myvalue = "" 

    def __init__(self): 
     #implement the borg patter (we are one) 
     self.__dict__ = self.__we_are_one 

    def myvalue(self, value=None): 
     if value: 
      self.__myvalue = value 
     return self.__myvalue 

conf = Config() 
conf.myvalue("Hello") 
conf2 = Config() 
print conf2.myvalue() 

這裏我們使用borg模式來創建一個singlton對象。無論您在代碼中如何使用此代碼,無論您將哪個模塊或類實例化爲配置,「myvalue」都是相同的。

3

創建空的superglobal.py模塊。
在你的文件做:

import superglobal 
superglobal.whatever = loacalWhatever 
other = superglobal.other 
1

這一點不明確你的原因是Python的故意不盡力支持這種事。命名空間是功能,使用它們對您有利。如果您想要在其他文件中定義的內容,請將其導入。這意味着通過閱讀您的源代碼,您可以找出所有東西來自哪裏,並且還使您的代碼更易於測試和修改。

4

在多年的實踐中,我對python的導入系統感到非常失望:處理正確是很複雜和困難的。另外,我必須在我寫的每個模塊中保留大量進口,這是皮塔餅。

命名空間是一個非常好的主意,它們是不可或缺的--- php沒有適當的命名空間,而且它是一團糟。

在概念上,編寫應用程序的一部分在於定義一個合適的詞彙表,這些詞彙將用於完成所需的工作。然而用傳統的方式,正是這些詞彙並不容易,因爲你必須先導入這個詞彙,然後導入它才能獲得訪問權限。

當命名空間在JavaScript社區就成爲關注的焦點,約翰的jQuery的名氣Resig的決定,提供全局命名空間的單一$變量是要走的道路:它只會影響全局命名空間最小,並提供方便的一切與jQuery。

同樣,我試驗了一個全局變量g,它在一定程度上起作用。基本上,您有兩種選擇:要麼有一個啓動模塊,必須在應用程序中的任何其他模塊之前運行,該模塊定義g中應該提供哪些內容,以便在需要時準備好。我嘗試的另一種方法是使g懶惰,並在需要新名稱時與自定義導入進行反應;所以當你第一次需要g.foo.frob(42)時,機制會在幕後嘗試類似import foo; g.foo = foo的東西。這樣做很難做得正確。

現在,除了標準庫和網站包以外,我幾乎完全拋棄了導入系統。大多數情況下,我都會爲軟管庫編寫包裝,因爲其中有90%的人無論如何都會有複雜的接口。然後我使用拼寫慣例在全局名稱空間中發佈這些包裝,以將碰撞風險降至最低。

我只說這是爲了緩解這樣一種印象,即修改全局命名空間是一種本質上是邪惡的東西,其他答案似乎是這樣。並非如此。什麼是邪惡就是輕率地做,或者被語言或包裝設計所強迫。

讓我補充一句話,因爲我幾乎肯定會在這裏得到一些解釋:宗教捍衛命名空間純度的人所做的所有進口中的99%是錯誤的。證明?你會在任何需要做三角測量的模塊foo.py的起始行中讀取,例如from math import sin。現在當你正確地使用import foo並查看該命名空間時,你會發現什麼?一些名爲foo.sin。但sin不是foo的接口的一部分,它只是一個幫手,它不應該混淆該名稱空間---因此,from math import sin as _sin或某些將是正確的。然而,幾乎沒有人這樣做。

我一定會用這些觀點引起一些激烈的評論,所以繼續。