2014-10-10 15 views
0

我不知道爲什麼下面的代碼工作。如果我主要評論斧頭任務,它就停止工作。斧頭如何進入功能範圍?這是python 2.7.2版本。使用matplotlib - 軸對象困惑變量作用域

經過多一點研究後,我發現在這個相同的代碼模塊中定義的函數可以看到主塊塊中的所有變量。我不知道python以這種方式工作!在同一個源文件中的所有函數都可以看到主塊塊中的每個變量。這並不符合我的期望!它似乎違反了什麼功能。我想這個例外是爲主要代碼塊,但我不會猜到它。

如何防止在此代碼模塊中定義的函數看到主塊塊中的所有變量?

import pylab as plt 

def f(): 
    ax.plot([1],[2]) # How is this ever defined? 
    return 

if (__name__ == "__main__"): 
    fig = plt.figure() 
    plt.clf() 
    ax = plt.subplot(111,polar=True) # If I comment this out, then ax is not defined error in function call 
    plt.hold(True) 
    f() 
+0

?在'f'裏面,解釋器尋找符號'ax'。如果找不到它,它會在您的全局範圍內查找,確實定義了「ax」。 – gg349 2014-10-10 08:58:55

+0

你應該修改你的函數來把'Axes'對象作爲參數。 – tacaswell 2014-10-10 13:56:35

回答

0

你不這樣做,因爲python中的函數總是可以訪問全局命名空間,這是它們模塊的命名空間。

您可以使用模塊來隔離功能。

只需在模塊中定義您的功能,即像mymod.py這樣的文件。它將只能訪問其模塊範圍。然後你可以使用它作爲myscript.py

#file myscript.py 
from mymod import myfunction 
#and now the function myfunction will not 'see' the variables defined in myscript.py 
1

「這並不讓我最希望的!這似乎違背了有什麼功能。」

然後,您應該避免在代碼中使用全局變量。請注意,您所指的主要模塊是該模塊/腳本的全局命名空間。有一個if語句,但這並不意味着「主」塊突然變成一個特殊功能。

你能做到這一點(這通常被認爲更好反正):

import pylab as plt 

def f(): 
    ax.plot([1],[2]) # This is now never defined 
    return 

def main(): 
    fig = plt.figure() 
    plt.clf() 
    ax = plt.subplot(111,polar=True) # ax is now local to the main() function only. 
    plt.hold(True) 
    f() 

if __name__ == "__main__": # No parentheses for an if-statement; very un-Pythonic 
    main() 

現在,這會導致錯誤每一次,因爲ax只被定義裏面main(),而不是在全球(模塊)命名空間。

+0

爲什麼這會被認爲更好?除了局部變量的微小性能改善之外,這是一個弱點。你不關心這樣的腳本中的命名空間污染,我會說,在這種情況下,最好不要實際使用'if __name__'子句,而只需編寫代碼。 – gg349 2014-10-10 09:13:16

+1

@GiulioGhirardo您喜歡(重新)使用腳本作爲模塊。也許'main()'是你可能想要從另一個腳本調用的一些函數,也許不是。想象一下,將這個腳本擴展爲一個模塊(也可以作爲一個獨立的腳本),然後編寫另一個(包裝)腳本,這個腳本需要例如命令行選項解析;後面的腳本可以導入這個腳本,然後執行main(可能帶有相同的關鍵字參數)。 – Evert 2014-10-10 09:16:51

+0

好吧,當然,同意。 – gg349 2014-10-10 10:24:47