2013-04-15 194 views
9

當閱讀python文檔和各種郵件列表時,我總是閱讀看起來有點像教條。全局變量應該像地獄一樣避免,它們是糟糕的設計...好吧,爲什麼不呢?但是有一些真實的生活狀況,我不知道如何避免這種模式。如何避免全局變量

假設我有一個GUI,可以從主菜單中加載幾個文件。可以使用通過所有GUI(例如,將顯示圖像的圖像查看器,並且可以通過不同的對話/插件對其執行各種動作)來使用與所加載的文件相對應的文件對象。

有什麼真的錯了以建設了如下設計:

  • Menu.py - >文件將被從這裏裝載
  • Main.py - >加載的文件對象可用於這裏
  • Dialog1.py - >或此
  • Dialog2.py - >或有
  • Dialog3.py - >或有
  • ...
  • Globals.py

其中Globals.py將存儲的字典,其關鍵是加載文件和值對應的文件對象的名稱。然後,從那裏,需要這些數據的代碼的各個部分將通過弱引用來訪問它。

對不起,如果我的問題看起來(或)是愚蠢的,但你看到任何優雅或全球免費的替代品?一種方法是將加載的數據字典封裝在Main.py的主應用程序類中,並將其視爲GUI的中央訪問部分。但是,這也會帶來一些複雜性,因爲即使這些對象需要這些數據,也應該可以從所有需要這些數據的對話中輕鬆訪問,即使這些對象是其直接的子對象。

非常感謝您的幫助

+1

全局變量不是邪惡的。邪惡是什麼使用它作爲一個可變變量。全局變量應儘可能保持靜態和「不變」。如果你不得不在globals.py中更改字典內容,那就不好了。除此之外,閱讀是可以的。 – CppLearner

+0

是的,全局「常量」沒問題,應該避免全局「變量」。 – monkut

+1

好吧,我明白你們的意思,但我仍然沒有看到一個有效的python替代方案,我建議在其中加載的數據字典可能會隨着時間發展(新加載的文件,刪除的文件) – Eurydice

回答

11

全局變量應該避免,因爲它們禁止代碼重用。多個小部件/應用程序可以很好地生活在同一個主循環中。這使您可以將您現在認爲是單個GUI的內容抽象爲一個可根據請求創建此類GUI的庫,以便(例如)單個啓動器可以啓動多個共享相同進程的頂級GUI。

如果您使用全局變量,這是不可能的,因爲多個GUI實例將勝過彼此的狀態。

全局變量的替代方法是將所需的屬性與頂層窗口小部件相關聯,並創建指向相同頂層窗口小部件的子窗口小部件。然後,例如,菜單操作將使用其頂層小部件訪問當前打開的文件以便對其進行操作。

+0

我會同意靜態成員變量/屬性(但不一定是作爲每實例屬性,如果再次僅用於常量,讀取目的)。但根據要求,有一些常量並不是很糟糕。只要確保他們理解Python可以做什麼和不可以做什麼:p – CppLearner

+0

如果我找到你的話,這樣的設計就像是一種樹,其中加載的數據字典將作爲根頂級小部件的屬性存儲。然後,應用程序的所有小部件都可以通過調用「topLevelParent」方法來訪問它。 – Eurydice

+0

你可以有一個'MainModel'來存儲文件名和頂級數據。有了QT,你將擁有主窗口,它將存儲文件名和頂級數據。打開和寫入文件的事件通常在頂級對象中處理,較低級別的對象不需要知道文件名。 – Eike

-1

我會通過將數據封裝在一個或多個類中並實現這些類的borg模式來管理全局數據。 請參閱Why is the Borg pattern better than the Singleton pattern in Python

+1

請不要宣傳博格模式。單例的要點是你有一個** single **實例,從而節省內存並確保相同的行爲。如果真的有必要在不同的子類中有不同的實例,那麼有辦法做到這一點,而不會損害基本的Singleton要求,每個類有一個實例。 – user4815162342

+3

Borg和Singleton模式都不能緩解全局變量的主要問題,那就是你有一個單一的全局狀態。事實上,單身模式只是一個很好的面向共享全局狀態的面向對象的界面,這正是文獻告訴的(沒有正確解釋爲什麼)OP要避免的。 – user4815162342

+1

我更喜歡一種實用的方法:全局變量又名單身又名borg模式只有在代碼寫入和讀取它們時纔是危險的。全局記錄器(所有客戶端寫入)都不是危險的,也不是數據庫連接池(所有客戶端都讀取)。如果開發者追隨書籍,但不應該忘記背景,那就好了。 – rocksportrocker