2014-11-06 1125 views
4

(有許多相似和更一般的問題,在通讀它們後嘗試解決方案,無法讓它們工作,因此請在此處詢問更具體情況的版本我看到的)Python:全局變量在模塊級別是未定義的

我想我真的很想 - 理解Python如何做OOP,因爲我的C#/ C++背景更多。所以這就是我現在想要做的。

我從兩個模塊開始設置我的項目的其餘部分,部分是作爲理智檢查和概念驗證。一個模塊在我去的時候將東西記錄到文件中,同時還存儲來自多個模塊的數據(最終將它們全部打包並根據請求轉儲它們)在PyCharm中執行所有這些操作,並提示錯誤警告,並使用Python 2.7

Module 1: 
    src\helpers\logHelpers.py 
    class LogHelpers: 
     class log: 
     def classEnter(): 
      #doing stuff 
     def __init__(self): 
      self.myLog = LogHelpers.log() #forgot to mention this was here initially 
     [..] various logging functions and variables to summarize what's happening 
    __builtin__.mylogger = LogHelpers 

Module 2: 
    src\ULTs\myULTs.py 
    mylogger.myLog.classEnter() 

(兩個模塊和根SRC \具有空初始化在他們 .py文件)

所以根據在這個階段這應該是在這裏工作的完全真棒響應(Python - Visibility of global variables in imported modules)但'mylogger'成爲'未解決的參考'

所以那是一種方法。我也嘗試了更直接的全球性(Python: How to make a cross-module variable?

Module 1: 
    src\helpers\logHelpers.py 
    class LogHelpers: 
     class log: 
     def classEnter(self): 
      #doing stuff 
     def __init__(self): 
      self.myLog = LogHelpers.log() #forgot to mention this was here initially 
     [..] various logging functions and variables to summarize what's happening 
    mylogger = LogHelpers 

    __init__.py 
    __all__ = ['LogHelpers', hexlogger] 
    from .logHelpers import * 

Module 2: 
    src\ULTs\myULTs.py 
    from helpers import mylogger 
    mylogger.myLog.classEnter() 

這個版本得到一個「參數‘自我’空缺」的classEnter,其中各種報告似乎表明錯誤意味着mylogger是未初始化(誤導錯誤代碼,但是這就是它似乎意味着)

然後,我試過這個..

Module 1: 
    src\helpers\logHelpers.py 
    class LogHelpers: 
     class log: 
     def classEnter(self): 
      #doing stuff 
     def __init__(self): 
      self.myLog = LogHelpers.log() #forgot to mention this was here initially 
     [..] various logging functions and variables to summarize what's happening 
    __mylogger = LogHelpers 

    __init__.py 
    __all__ = ['LogHelpers', hexlogger] 
    from .logHelpers import * 

Module 2: 
    src\ULTs\myULTs.py 
    from helpers import mylogger 

    def someFunction(self): 
     global mylogger 
     mylogger.myLog.classEnter() 

這個版本獲得誤差「全局變量是在模塊級未定義」當我將鼠標懸停全球mylogger的。

然後,每個其他模塊的想法顯然跟蹤自己的類的實例,如果我最終不得不我可以使用該方法,並協調他們..但這是一種黑客考慮我是什麼試圖去做。

這就是我所處的地方,這就是我想要做的事情的要點......我正在儘可能多地閱讀類似的問題,但他們都似乎回到了這些(似乎沒有工作)或說'不這樣做'(這通常是很好的建議,但我並不真正喜歡Pythony的方法來保持多個正在進行的非靜態類爲大型項目 - 除了將它們全部放在一個目錄中)

想法? (如何不好我會重整的Python在這裏?)

[編輯]意見的基礎上試過,完全消除了內部類迷你版: 好了,做了基於本地的迷你級你說:

class testClass: 
    def __init__(self): 
     self.testVar = 2 
    def incrementVar(self): 
     self.testVar += 1 
myClass = testClass() 

通過init進行設置。PY

__all__ = [myClass] 
from .logHelpers import myClass 

又到其他模塊和

from helpers import myClass 
class Test_LogHelpers(unittest.TestCase): 
    def test_mini(self): 
     myClass.incrementVar() 

跑了,而不是直接在原點:(看着PyCharm,沒有任何全球.. NameError: name 'myClass is not defined

所以還是(和仍然需要以存儲狀態)

[編輯]添加回溯:

Traceback (most recent call last): 
    File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 3.4.1\helpers\pycharm\utrunner.py", line 124, in <module> module = loadSource(a[0]) 
    File "C:\Program Files (x86)\JetBrains\PyCharm Community Edition 3.4.1\helpers\pycharm\utrunner.py", line 40, in loadSource module = imp.load_source(moduleName, fileName) 
    File "C:\[...mylocation...]\py\src\ULTs\LogHelpers_ULT.py", line 3, in <module> from helpers import myClass 
    File "C:\[...mylocation...]\py\src\helpers\__init__.py", line 7, in <module> 
    __all__ = [myClass] 
NameError: name 'myClass' is not defined 

=============================================== =============================

kk,我知道它與微型工作。我不知道爲什麼其他方法不行,但這似乎解決了問題。 (參考資料:http://docs.python-guide.org/en/latest/writing/structure/http://mikegrouchy.com/blog/2012/05/be-pythonic-__init__py.html

**logHelpers.py** 
[... some static logging functionality ...] 

class testClass: 
    def __init__(self): 
     self.testVar = 2 

    def incrementVar(self, source): 
     self.testVar += 1 
     mylogger.myLog.info(source + " called, new val: " + str(self.testVar)) 
myClass = testClass() 

**test_LogHelpers_ULT.py** 
import unittest 

from helpers.logHelpers import myClass  

class Test_LogHelpers(unittest.TestCase): 
    def test_mini(self): 
     myClass.incrementVar("LogHelpers") 

出於某種原因跳過 初始化的.py (和保留爲空),並打算爲明確的進口工作。它也維護狀態 - 我創建了測試文件的副本,並且我的日誌輸出正確地具有「3」用於第一個文件調用幫助器,而「4」用於第二個文件調用幫助器。

感謝Daniel Roseman的幫助和建議,他們讓我看起來更朝正確的方向看。如果你能發現爲什麼以前的東西無法正常工作,只需要增加對我的這種語言的理解就會非常感謝,但我會繼續前進,並將你的答案標記爲「已回答」,因爲它有一些非常有用的反饋。

回答

9

在我開始之前,請注意PyCharm警告並非真正的Python錯誤:如果您運行代碼,您可能會獲得更多有用的反饋信息(請記住,像Python這樣的動態語言的靜態分析只能讓您獲得更多,直到你真正運行代碼才能解決問題)。首先,真的不清楚爲什麼你在這裏有嵌套類。外部類似乎完全沒用;你應該刪除它。

有關「self」錯誤消息的原因是您已定義實例方法,該實例方法只能在log的實例上調用。您可以製作mylogger(絕對不需要雙下劃線前綴)實例:mylogger = log() - 然後導入該實例,或者導入該類並將其實例化到使用位置。

因此,在您的第一個片段中,錯誤信息非常明確:您尚未定義mylogger。使用我上面的建議,你可以做from helpers import mylogger,然後直接撥打mylogger.classEnter()

最後,我看不到陳述在做什麼someFunction。除非您計劃將其重新分配到您的範圍內,並且將重新分配反映在全球範圍內,否則無需聲明全球名稱。你沒有這樣做,所以不需要global

順便說一句,你還應該問你是否需要內部log類。一般來說,類只有在需要在對象中存儲某種狀態時纔有用。在這裏,正如你的文檔字符串所說的那樣,你有一組實用方法。那麼爲什麼要把他們放在一個班級?只需在logHelpers模塊中將它們設置爲頂層函數(順便說一下,Python模式更喜歡lower_case_with_underscore模塊名稱,所以它應該是「log_helpers.py」)。

+0

非常感謝您的反饋 - 我會盡快嘗試它(只要我今天晚些時候再次接近代碼) 我在保持嵌套類,因爲我想從我可以從哪裏接觸一個單一的聯繫點擴展到相關但功能不同的不同功能。 (簡單的日誌記錄,現在聲明,更晚)。我可以通過擁有各種類和一個具有多個變量的類來完成同樣的任務,每個類都存儲一個類,只是試圖使定義保持內部,因爲不應該單獨實現類/保持自動完成清理。 – 2014-11-06 16:35:20

+0

當我試圖複製我試過的各種東西時,這些額外的__都是一個錯誤,將它們刪除。 – 2014-11-06 16:40:38

+0

那麼,請記住嵌套一個類不會給內部類提供對外部類的任何特權訪問,所以它很少有任何好處。通常在Python中,嵌套的元素是包和模塊,而不是類。 – 2014-11-06 16:52:17