2010-09-04 26 views
2

我是python的新手,我一直在閱讀使用global將變量傳遞給其他函數的函數,這被認爲是noobie,也是一種不好的做法。我想擺脫使用全局變量,但我不知道該怎麼做。將全局變量傳遞給類和函數的替代方法

現在我有一個我已經在wxPython中創建的UI作爲它自己的單獨的類,並且我有另一個從.ini文件加載設置的類。由於UI中的設置應與.ini中的設置相匹配,因此我如何傳遞這些值?我可以使用類似於:Settings = Settings()然後將變量定義爲類似self.settings1的變量,但是之後我必須將Settings一個全局變量傳遞給我的UI類(如果我在其中分配main(),則不會這樣做)。

那麼傳遞這些變量的正確和pythonic方法是什麼?

編輯:下面是我正在使用的代碼,我試圖讓它像Alex Martelli的例子那樣工作。下面的代碼保存在Settings.py

import ConfigParser 

class _Settings(): 
    @property 
    def enableautodownload(self): return self._enableautodownload 
    def __init__(self): 
     self.config = ConfigParser.ConfigParser() 

     self.config.readfp(open('settings.ini')) 
     self._enableautodownload=self.config.getboolean('DLSettings', 'enableautodownload') 

settings = _Settings() 

每當我試着從另一個文件,我得到參考Settings.settings.enableautodownloadAttributeError: 'module' object has no attribute 'settings'。我究竟做錯了什麼?

編輯2:不要介意這個問題,我重新輸入了代碼,它現在可以工作,所以它一定是一個簡單的拼寫或語法錯誤。

+0

有些情況下,使用全局變量很好,在這種情況下,在各處傳遞對象的普遍性被不便之處所抵消。但是,當你開始時,你應該避免這種情況,直到你瞭解何時適合。 – 2010-09-04 03:14:25

+0

看起來像正確的導入應該是'從設置導入設置',那麼你可以使用它,比如'print settings.enableautodownload'。 – flow 2010-09-04 14:29:51

回答

4

global變量的替代品很多 - 主要是:

  • 明確的函數的參數,類調用來創建自己的實例,等一個(這通常是最清楚的,因爲它使得依賴最明確,在可行的情況下,不要太重複);
  • 對象的實例變量,當需要訪問這些值的函數是同一對象上的方法時(也可以,以及使用OOP的合理方法);
  • 「訪問器函數」提供值(或具有值的屬性或屬性的對象)。

每個這些(特別是在第一和第三個)是用於值的名字必須由所有雜重新綁定,但只訪問特別有用。 global真正的大問題在於它提供了一個「祕密通信通道」(不是密碼學意義上的,而是字面意義上的:顯然分開的函數實際上可以相互依賴,相互影響,通過全局值功能簽名中的「顯而易見」 - 這使得代碼難以測試,調試,維護和理解)。

對於您的特定問題,如果您從不使用global語句,而是從各處以「只讀」方式訪問設置(並且可以通過使所述對象的屬性成爲只讀屬性!),然後在一個單一的,然後不變的模塊級實例上執行「只讀」訪問,並不算太壞。即在某些模塊foo.py

class _Settings(object): 
    @property 
    def one(self): return self._one 
    @property 
    def two(self): return self._two 
    def __init__(self, one, two): 
     self._one, self._two = one, two 
settings = _Settings(23, 45) 

,並從其他地方一樣,import foo然後只需訪問foo.settings.onefoo.settings.two需要。請注意,我已經用一個前導下劃線命名類(就像只讀屬性的兩個實例屬性一樣),以表明它並不意味着從模塊的「外部」使用 - 只有settings對象是應該是(沒有強制執行 - 但任何違反此類要求的隱私的用戶顯然是唯一負責任何可能發生的混亂的一方;-)。

+0

謝謝你的例子,但我似乎無法讓我的代碼工作。我已經將它編輯到問題中,所以你能告訴我我做錯了什麼嗎? – FlowofSoul 2010-09-04 13:57:10

+0

@Flowof,在您開始嘗試從另一個地方使用'Settings.settings'之前,'print settings .__ file__',以確認*您準確地導入了哪些特殊名稱(混合大小寫模塊名稱通常會導致問題在不區分大小寫的文件系統中,比如典型的Windows系統和Mac系統中的所有文件系統,所以他們現在強烈建議不要使用全小寫的文件系統)。在令人驚訝的情況下,您實際上已經導入了正確的文件,請添加'print dir(Settings)'以查看其中定義了**的**。請修改您的問題以提供此重要信息。 – 2010-09-04 14:38:41

+0

一切都正確導入,所以我只是重新輸入代碼,現在它的作品。謝謝你的幫助。 – FlowofSoul 2010-09-05 01:58:48

相關問題