日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Python中令人頭疼的變量作用域問題,終于弄清楚了

 我們經常聽說Python函數(shù)訪問局部變量、全局變量;在定義裝飾器的時候,還會使用自由變量。這些不同的變量是如何賦值、初始化、查找及修改的呢?各自的作用細則又是什么樣的呢?本篇嘗試解答這個問題。

在鶴峰等地區(qū),都構建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產品創(chuàng)新能力,以專注、極致的服務理念,為客戶提供網(wǎng)站制作、成都網(wǎng)站制作 網(wǎng)站設計制作按需求定制設計,公司網(wǎng)站建設,企業(yè)網(wǎng)站建設,成都品牌網(wǎng)站建設,成都全網(wǎng)營銷,外貿網(wǎng)站制作,鶴峰網(wǎng)站建設費用合理。

Python中的變量名可以指代變量、函數(shù)、類、對象等。一般來說,每個對象都有一個變量名指向,更準確說是 綁定。

作用域的必要性

為啥變量要有作用域呢?

我們在Python里遇到的內置、局部、全局及自由變量,就是說變量的作用域。

語言區(qū)分作用域,是為了復用變量名。引入作用域,相當于給變量劃分了各自的“隔離區(qū)”,在不同”隔離區(qū)“里,查找變量變得很容易。

正是因為有了作用域,我們在函數(shù)內才可以隨意使用變量名,而不擔心其與全局變量、其他函數(shù)中的變量沖突——因為這兩個作用域是分割的。

BASIC語言只有全局變量,你能想象嗎?你在一個函數(shù)里命名的循環(huán)變量i,很可能跟全局變量沖突。寫起程序來,舉步維艱。且會導致很多修改、檢索問題,維護很困難。

Python變量定義的時間和空間

Python 有哪些作用域呢?

Python是動態(tài)類型語言,變量是在定義的時候賦值的。這句話的意思我們分以下幾個方面來理解:

  • a = 1 賦值時定義變量
  • from tools import cubie 導入時定義變量 cubie
  • def fun():pass 定義函數(shù),綁定變量fun
  • def fun(name=None):pass 定義變量name為函數(shù)fun的形式變量(也是局部變量),同時定義函數(shù),綁定便令fun
  • class Car:pass 定義類,綁定類名Car

以上,我們弄清了變量定義的時刻,下面來看變量的作用域,也就是變量的活動空間怎么規(guī)定出來的。

變量作用域取決于其 定義位置。

  • 定義在函數(shù)內部的變量、定義在函數(shù)聲明中的形式參數(shù),視為局部變量。
  • 定義在 .py 文件內的,且函數(shù)、類之外的變量,視為全局變量。
  • 定義在函數(shù)中,嵌套函數(shù)外,且被嵌套函數(shù)引用的變量,視為自由變量。
  • 定義在builtin中的變量,視為內置變量。

面對如此復雜的四種變量作用域,用一個例子來說明它們的訪問規(guī)則。

LEGB規(guī)則

四個作用域遵循LEGB規(guī)則,讓我們用一個例子來說明。

 
 
 
  1. import builtins 
  2.  
  3. builtins.b = 'builtins' 
  4. g = 'global' 
  5.  
  6. def outer(o1,o2='o2'): 
  7.     e = 'enclose' 
  8.     def inner(i1,i2='i2'): 
  9.         print(i1,i2,o1,o2,e,g,b) 
  10.     return inner  
  11.  
  12. fun = outer('o1')  
  13. fun('i1') 

其輸出為 i1 i2 o1 o2 enclose global builtins

可見,在outer函數(shù)的嵌套函數(shù)inner中的輸出語句 print(i1,i2,o1,o2,e,g,b) 是本程序的重點。其具體執(zhí)行情況如下:

  • print i1和i2,毫無疑問的局部變量。
  • print o1和o2,本地作用域沒有,向上查找到outer函數(shù)形參。形參也為局部變量,所以該變量實際定義在outer函數(shù)內,inner這個內嵌函數(shù)外,而inner內部引用了這個變量,所以視為自由變量。
  • print e,本地作用域沒有,類似上例,視為自由變量。
  • print g,本地作用域沒有,自由變量作用域(閉包)沒有,一直上溯到全局作用局找到。
  • print b,本地作用域沒有,自由變量作用域(閉包)沒有,全局作用局沒有,一致上溯到內置變量空間找到。

至此,LEGB規(guī)則呼之欲出:在本地空間尋找不到的變量,逐級向上級尋找。這里的LEGB分別指代Local,Enclose,Global和Builtin。

在函數(shù)中讀取和賦值全局變量,在內嵌函數(shù)中讀取和賦值自由變量,會有一些不同的地方。

nonlocal 和 global

對變量名的賦值和引用,是兩種不同的情況:

  • 賦值:創(chuàng)建一個變量或者修改。
  • 引用:檢索其值。

以上兩者的差別,會導致我們在函數(shù)中:

  • 賦值一個
  1. 全局變量:等于創(chuàng)建一個局部變量。
  2. 自由變量:等于創(chuàng)建一個局部變量。
  • 引用:正常檢索其值。

我們修改上例中的inner函數(shù)為如下形式:

 
 
 
  1. def inner(i1,i2='i2'): 
  2.     e = 'enclose' 
  3.     g = 'inner global' 
  4.     print(i1,i2,o1,o2,e,g,b) 

在嵌套函數(shù)內,重新定義了g變量,其他語言一般理解這是重新賦值全局變量。但是我們看上條規(guī)則:在函數(shù)中,賦值一個全局變量時,等于創(chuàng)建一個局部變量。就是說此時的g已經是局部變量了——在程序最后的 print(g) 語句輸出 global,而不是修改后的 inner global 也驗證了以上規(guī)則。

完整代碼如下:

 
 
 
  1. import builtins 
  2.  
  3. builtins.b = 'builtins' 
  4. g = 'global' 
  5.  
  6. def outer(o1,o2='o2'): 
  7.     e = 'enclose' 
  8.     g = 'inner global' 
  9.     def inner(i1,i2='i2'): 
  10.         print(i1,i2,o1,o2,e,g,b) 
  11.     return inner  
  12.  
  13. fun = outer('o1')  
  14. fun('i1') 
  15.  
  16. print(g) 

輸出結果如下:

 
 
 
  1. i1 i2 o1 o2 enclose inner global builtins 
  2. global 

不重新賦值,只是使用全局變量和自由變量,則沒有問題。

自由變量也是類似的情況。

為了解決局部作用域中賦值全局變量和自由變量導致的變成局部變量問題,Python引入關鍵字 global 和 nonlocal 。

 
 
 
  1. def inner(i1,i2='i2'): 
  2.     global g 
  3.     nonlocal e 
  4.     g = 'inner global' 
  5.     e = 'inner enclose' 

此時的賦值,則分別是對全局變量和自由變量的操作,而非新建局部變量。

完整代碼如下:

 
 
 
  1. import builtins 
  2.  
  3. builtins.b = 'builtins' 
  4. g = 'global' 
  5.  
  6. def outer(o1,o2='o2'): 
  7.     e = 'enclose' 
  8.     def inner(i1,i2='i2'): 
  9.         global g 
  10.         nonlocal e 
  11.         g = 'inner global' 
  12.         e = 'inner enclose' 
  13.         print(i1,i2,o1,o2,e,g,b) 
  14.     return inner  
  15.  
  16. fun = outer('o1')  
  17. fun('i1') 
  18.  
  19. print(g) 

輸出結果如下:

 
 
 
  1. i1 i2 o1 o2 inner enclose inner global builtins 
  2. inner global 

總結

  • Python的作用域分為四種,分別是局部、全局、自由和內置;
  • 定義變量的位置決定了變量的作用域;
  • 作用域的查找遵守LEGB規(guī)則;
  • 為了在局部作用域中修改全局變量和自由變量,引入了 global 關鍵字和 nonlocal 關鍵字。

分享題目:Python中令人頭疼的變量作用域問題,終于弄清楚了
網(wǎng)頁網(wǎng)址:http://m.5511xx.com/article/cdpdeis.html