哪裡出問題了
python 中,使用 global 會將全域變數設為本函數可用。同時,在函數內部存取變數會先本地再全域。
在巢狀函數中,使用 global 會產生不合常理的行為。
上代碼:
In [96]: def x(): b = 12 def y(): global a,b a = 1 b = 2 y() print "b =",b ....: In [97]: a = 111 In [98]: del b In [99]: x() b = 12 In [100]: a Out[100]: 1 In [101]: b Out[101]: 2
而在函數 x() 中,沒有用 global,此時的b使用本地。所以 print 會印本地 b
為什麼會印 12 ?還有 In[101]的 b 為 2 該怎麼解釋?
y(),使用的 global 竟然沒把 x() 的 b = 12 導進來。
在函數 y() 中,語句 global a,b 使a,b擴展為全局,所以,在最高層,就算沒有 b(In[98]),也會產生 b(In[101])。
也就是說, global a,b ,會認為 a 和 b 是最外層的變數。
再試一下:
In [102]: def x(): b = 12 def y(): global a,b a = 1 y() print "b =",b .....: In [103]: a = 111 In [104]: del b In [105]: x() b = 12 In [106]: a Out[106]: 1 In [107]: b --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-107-3b5d5c371295> in <module>() ----> 1 b NameError: name 'b' is not defined
報錯了! y() global b 後沒賦值,頂層就沒有 b。這說明,global 只是引入名稱,並不做賦值等操作。
global 不會管變數存不存在,只導入名稱,對該名稱的操作會反應到 ‘最高層名稱空間‘。
再來:
In [109]: a = 111 In [110]: del b --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-110-745f2abe7045> in <module>() ----> 1 del b NameError: name 'b' is not defined In [111]: def x(): b = 12 def y(): global a,b a = 1 print b y() print "b =",b .....: In [112]: x() --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-112-7354d77c61ac> in <module>() ----> 1 x() <ipython-input-111-c05fc67a1e82> in x() 5 a = 1 6 print b ----> 7 y() 8 print "b =",b 9 <ipython-input-111-c05fc67a1e82> in y() 4 global a,b 5 a = 1 ----> 6 print b 7 y() 8 print "b =",b NameError: global name 'b' is not defined
這就確定了 內層y() 的 global 不會 導入 x() 的東西。
那麼,內層函數怎麼使用正確的外層函數的變數呢?
解內層函數參數傳遞問題
一、
首先,若只是取值,則不需要做任何處理。
In [119]: def x(): .....: a = 12 .....: def y(): .....: print a .....: y() .....: In [120]: x() 12 In [121]:
在 y() 中,一旦為 a 賦值,a 立刻變內部變數。
In [121]: def x(): .....: a = 12 .....: def y(): .....: print "before a =",a .....: a = 1 .....: print "then a =",a .....: y() .....: In [122]: x() before a =--------------------------------------------------------------------------- UnboundLocalError Traceback (most recent call last) <ipython-input-122-7354d77c61ac> in <module>() ----> 1 x() <ipython-input-121-d8fbc0dba399> in x() 5 a = 1 6 print "then a =",a ----> 7 y() 8 <ipython-input-121-d8fbc0dba399> in y() 2 a = 12 3 def y(): ----> 4 print "before a =",a 5 a = 1 6 print "then a =",a UnboundLocalError: local variable 'a' referenced before assignment
一旦在函數 y() 的某處給 a 賦值,則在賦值前,python 會認為 a 不存在。
同時發現 python2 的 print 會一個一個的 輸出。有鑑於此,我又在 python3 中試了,發現他是 一起輸出。但這不是本文重點,折疊之。
In [7]: def x(): a = 1 def y(): print("before a=",a) a = 10 print("then a=",a) y() ...: In [8]: x() --------------------------------------------------------------------------- UnboundLocalError Traceback (most recent call last) <ipython-input-8-7354d77c61ac> in <module>() ----> 1 x() <ipython-input-7-6e01e7317b24> in x() a = 10 print("then a=",a) ----> 7 y() <ipython-input-7-6e01e7317b24> in y() a = 1 def y(): ----> 4 print("before a=",a) a = 10 print("then a=",a) UnboundLocalError: local variable 'a' referenced before assignment
同時發現 python程式碼運行前 會先掃一遍程式碼的,而不是單純的一行一行的執行。
同時發現回傳 UnboundLocalError,而不是 NameError。注意到 'unbound‘,這是官方概念。用'unbound' 來描述就是:global 會將頂層變數名稱綁定到本地變數名稱,同時變化,是為'引用';python 偵測到a = 1時,意識到a 是本地的,所以在a '指向一個物件'(因為python變數皆為引用),之前,呼叫a 是非法行為,但這種行為區別於NameError,就定義為unbound local。
二、
使用 可變變量,如 list,dict
In [127]: def x(): .....: l = ["in msg"] .....: def y(): .....: msg = l[0] .....: print "msg =",msg .....: l[:] = ["out msg"] .....: y() .....: print l[0] .....: In [128]: x() msg = in msg out msg
沒有報錯,完美!
要注意 語句 l[:] = ["out msg"] ,使用切片賦值,否則,
In [129]: def x(): l = ["in msg"] def y(): msg = l[0] print "msg =",msg l = ["out msg"] y() print l[0] .....: In [130]: x() --------------------------------------------------------------------------- UnboundLocalError Traceback (most recent call last) <ipython-input-130-7354d77c61ac> in <module>() ----> 1 x() <ipython-input-129-d44e750e285f> in x() 5 print "msg =",msg 6 l = ["out msg"] ----> 7 y() 8 print l[0] 9 <ipython-input-129-d44e750e285f> in y() 2 l = ["in msg"] 3 def y(): ----> 4 msg = l[0] 5 print "msg =",msg 6 l = ["out msg"] UnboundLocalError: local variable 'l' referenced before assignment
又出 UnboundLocalError 了,因為 第六行程式碼 為 l 分配了 一個新的 list。
三、
利用參數傳遞。
In [136]: def x(): .....: a, b = 1, 2 .....: def y(a = a, b = b): .....: a, b = 3, 4 .....: return a, b .....: a, b = y() .....: print a, b .....: In [137]: x() 3 4
注意,不要在預設參數上放 list等可變物件。
以上所述是小編給大家介紹的PYTHON 中使用 GLOBAL引發的一系列問題,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回覆大家的。在此也非常感謝大家對腳本之家網站的支持!

文章討論了由於語法歧義而導致的Python中元組理解的不可能。建議使用tuple()與發電機表達式使用tuple()有效地創建元組。 (159個字符)

本文解釋了Python中的模塊和包裝,它們的差異和用法。模塊是單個文件,而軟件包是帶有__init__.py文件的目錄,在層次上組織相關模塊。

文章討論了Python中的Docstrings,其用法和收益。主要問題:Docstrings對於代碼文檔和可訪問性的重要性。

本文討論了Python中的“ Pass”語句,該語句是函數和類等代碼結構中用作佔位符的空操作,允許在沒有語法錯誤的情況下實現將來實現。

文章在Python中討論 /和//運營商: / for for True Division,//用於地板部門。主要問題是了解它們的差異和用例。 Character數量:158


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

SublimeText3漢化版
中文版,非常好用

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中