2012-04-20 38 views
0

我不確定Python的作用域規則。如果我正在使用Python控制檯並定義一個變量,然後導入一個模塊並在該模塊中調用一個函數,有沒有辦法在函數中引用該變量?例如:引用函數中的Python控制檯變量

>> option = 2 
>> import choosingModule 
>> choosingModule.choosingFunction() 

然後在choosingModule:

def choosingFunction(): 
    if option == 0: 
     doThis() 
    elif option == 1: 
     doThat() 
    elif option == 2: 
     doTheOtherOne() 
    else: 
     doWhateverYouFeelLike() 

顯然,這是一個簡單的例子。我想這樣做的原因是我有四個不同版本的函數,我希望能夠從控制檯中選擇使用哪一個版本。該函數被調用的代碼相當深入,所以我不想通過每個函數調用傳遞參數,特別是因爲我只需要在測試階段對它們進行比較;當它達到生產版本時,將只使用其中一個。

那麼,有什麼辦法可以在被調用函數中引用Python控制檯變量嗎?或者,有沒有其他方法可以做我需要的?

回答

1

當你運行REPL,你是__main__模塊,使您可以導入並從它使用的變量:

def choosingFunction(): 
    option = __import__('__main__').option 
    if option == 0: 
     doThis() 
    elif option == 1: 
     doThat() 
    elif option == 2: 
     doTheOtherOne() 
    else: 
     doWhateverYouFeelLike() 

然而,一個更好的辦法,如果你不完全做到這一點需要要在控制檯中定義的變量是將其設置爲choosingModule。然後:

def choosingFunction(): 
    global option 
    if option == 0: 
     doThis() 
    elif option == 1: 
     doThat() 
    elif option == 2: 
     doTheOtherOne() 
    else: 
     doWhateverYouFeelLike() 
>>> import choosingModule 
>>> choosingModule.option = 2 
>>> choosingModule.choosingFunction() 

但是,您應該單獨選用,同時測試。 請不要在生產代碼中使用這些。

+0

您的第一個解決方案給我錯誤消息「AttributeError:'FakeModule'對象沒有屬性'選項'」。 – thornate 2012-04-20 04:31:44

+0

@thornate:這看起來像是一個IPython的東西。不幸的是,我無法複製那個錯誤。 – icktoofay 2012-04-20 04:36:01

0

我建議您將該變量保留在全局範圍內,並使用global聲明訪問它。

關鍵字global允許您引用全局名稱空間中的變量,儘管在函數調用方中存在另一個具有相同名稱的變量。

例如:這將打印 「橘子」

def foo(): 
    def bar(): 
     return fruit 
    fruit = "tangerine" 
    return bar2() 

fruit = "banana" 
print(foo()) # will print "tangerine" 

但是,這將打印 「香蕉」。

def foo2(): 
    def bar2(): 
     global fruit # fetch me the fruit in the global scope 
     return fruit 
    fruit = "tangerine" 
    return bar2() 

fruit = "banana" 
print(foo2()) # will print "banana" 

沒有全球性的關鍵字,解釋器將遵循「LEGB規則」,以便找到你想引用變量:

  1. 大號 OCAL範圍:第一,它是將搜索本地作用域中的變量,即函數語句正在執行的作用域。本地範圍在每次調用函數時創建。
  2. E nclosing作用域:其次,解釋器將在「封閉函數本地」中查找變量,即函數插入(聲明)的函數。這就是水果變量返回水果裏面的發現bar()
  3. G lobal:如果在上面的命名空間中找不到變量,python會嘗試在全局變量中找到它。在全球聲明力量蟒蛇的使用情況,以尋找它只能在全球範圍內,因此跳過1個2
  4. uiltins:最後,蟒蛇將試圖找到內置功能中的變量和常量。這裏沒有魔法。

如果所有的搜索上面無法找到變量名,Python會引發一個NameError例外:

$ NameError: name 'fruit' is not defined 

然後,你可以這樣做:

def choosingFunction(): 
    global option 
    if option == 0: 
     doThis() 
    elif option == 1: 
     doThat() 
    elif option == 2: 
     doTheOtherOne() 
    else: 
     doWhateverYouFeelLike() 

>> option = 2 
>> import choosingModule 
>> choosingModule.choosingFunction() 

記住在調用你的模塊中依賴全局變量的存在被認爲是一種非常糟糕的做法,不得嚴重使用它。 ;)

有關全球聲明的更多信息,請查閱文檔:Python 3.xPython 2.7。 有關範圍和名稱空間規則的信息,請檢查here(Python 3.x)或here(Python 2.7)。