开心六月综合激情婷婷|欧美精品成人动漫二区|国产中文字幕综合色|亚洲人在线成视频

    1. 
      
        <b id="zqfy3"><legend id="zqfy3"><fieldset id="zqfy3"></fieldset></legend></b>
          <ul id="zqfy3"></ul>
          <blockquote id="zqfy3"><strong id="zqfy3"><dfn id="zqfy3"></dfn></strong></blockquote>
          <blockquote id="zqfy3"><legend id="zqfy3"></legend></blockquote>
          打開APP
          userphoto
          未登錄

          開通VIP,暢享免費(fèi)電子書等14項超值服

          開通VIP
          如何避開變量作用域的陷阱

          講這個知識點之前,先看一個例子:

          x=99
          def func1():
          global x
          x=88

          def func2():
          global x
          x=77

          問題:大家覺得x最后的是值到底是多少:88還是77?先思考一下,最后我來揭曉謎底....

          python的變量跟其他語言一樣,分為全局變量和局部變量,這個概念比較好理解,我們來看看python中是如何實現(xiàn)的:

          1.全局變量與局部變量

          x=100
          def func():
          print ('Inside func: x is {}'.format(x))
          func()
          print 'x is still:{}'.format(x)

          >> # 打印結(jié)果
          Inside func: x is 100
          x is still:100

          這個比較好理解x是全局變量,作用域是整個文件,函數(shù)內(nèi)部是可以引用的.接著看下面一個例子:

          x=100
          def func():
          x=10 #多了這一行
          print ('Changed local x to :{}'.format(x))

          func()
          print 'x is still:{}'.format(x)

          >>># 打印結(jié)果
          Changed local x to :10
          x is still:100 

          大家看在函數(shù)外部有一個變量x,在函數(shù)內(nèi)部也有一個變量x,這兩個變量雖然名字長的一樣,但是是完全不同的:

          函數(shù)內(nèi)部的是本地變量,它的生命周期只在函數(shù)內(nèi)部,出了函數(shù)就結(jié)束了,

          而x在函數(shù)外部模塊文件中聲明的(python一個文件也叫一個模塊),是全局變量,不會被函數(shù)里面的局部變量影響,所以最后print的x還是100,

          有人要問了,有的時候我需要讓這個全局變量在函數(shù)里面處理,改變它的值,怎么辦?這個python早就考慮到了,往下看~~

          2.全局變量聲明:

          x=100
          def func():
          global x #注意加了一個global 關(guān)鍵字,表示x是全局作用域
          print 'x is :{}'.format(x)
          x=10
          print ('Changed local x to :{}'.format(x))

          func()
          print 'Value of x:{}'.format(x)

          >>> # 打印結(jié)果
          x is :100
          Changed local x to :10
          Value of x:10

          這個函數(shù)內(nèi)部多了一個global關(guān)鍵字,結(jié)果就差很多:

          原因在于x被聲明為函數(shù)內(nèi)的全局變量,通過global這個語句是自己明確地映射到了模塊的作用域

          函數(shù)內(nèi)對x重新賦值x=10,會改變函數(shù)外x的值,所以最后print x是10

          全局變量簡單說就是這3點:

          全局變量是位于模塊文件內(nèi)部的頂層的變量名

          全局變量如果是在函數(shù)內(nèi)被改變的話,一定要用global

          全局變量名在函數(shù)內(nèi)部不經(jīng)過聲明也可以被引用

          3.函數(shù)內(nèi)的變量解析原則

          有的書上叫LEGB法則,其實講白了就是下面4個過程,當(dāng)在函數(shù)中使用沒有聲明過的變量時,python的搜索順序是:

          先是在函數(shù)內(nèi)部的本地作用域(L)  

          然后是在上一層的函數(shù)的本地作用域(E)

          然后是全局作用域(G)

          最后是內(nèi)置作用域(B)

          簡單說就是從局部到中央,好比你找一個人,村里找不到找鄉(xiāng)->鄉(xiāng)里找不到找市里->市里找不到找到全國檔案局

          我們來一一解釋一下這些原則

          1).本地函數(shù)

          在函數(shù)內(nèi)部(def或者lambda)通過任何方式賦值的,而且沒有在該函數(shù)內(nèi)聲明為全局變量的變量名

          2).上層函數(shù)的本地作用域

          python函數(shù)是支持嵌套,而且多層嵌套,當(dāng)你在最里層的函數(shù)找不到這個變量的時候,會往上一層的函數(shù)找,一層一層由內(nèi)往外找,舉個例子

          def f1():
          x=100
          def f2():
          print
          f2()

          print f1()
          >>
          100
          None 

          #因為f2()打印了之后沒有return,對沒有return的函數(shù)就默認(rèn)返回None

          我來解釋一下:

          def定義了一個f1()函數(shù),里面又嵌套了一個f2()函數(shù),這個def生成了一個函數(shù)并將其賦值給變量名f2

          f2是f1的本地作用域內(nèi)的一個本地變量,可以把f2看做一個臨時函數(shù),僅僅在f1內(nèi)部執(zhí)行的過程中存在.

          f2函數(shù)干了一件事打印x,當(dāng)在f2()內(nèi)部找不到的時候,就通過LEGB法則往上找,f1()里面找到了x.

          3).全局(模塊)

          在模塊文件的頂層賦值的變量名,或者在該文件中的def生成的名為全局變量的變量名(函數(shù)內(nèi)global聲明的變量)

          4).內(nèi)置的作用域

          這個很多初學(xué)者不明白,啥內(nèi)置,內(nèi)置了什么,其實很簡單,python在運(yùn)行之前會自動的引用一個內(nèi)置模塊,叫做__builein__,這是python的一個標(biāo)準(zhǔn)庫模塊,直接import進(jìn)來,可以用dir(__builein__)看一下,里面都是預(yù)定義的一些變量名

          是不是看到了很多熟悉的面孔(type,sum.sorted,open),對的那些就是內(nèi)置的變量名,前面3種方法都找不到了就會去內(nèi)置作用域這個列表里面.

          換句話時候若你本地變量有一個跟內(nèi)置變量一樣的,就會被本地變量覆蓋 

          def hider():
          sum='newsum'
          return sum([1,2,3])

          print hider()
          >>TypeError: 'str' object is not callable

          就是因為LEGB法則,本地的sum變量把內(nèi)置作用域的sum變量覆蓋了

          下面總結(jié)一下:

          開頭的例子的答案,其實X的值不是88也不是77,而是都有可能,因為不確定你先調(diào)用那個函數(shù),變量的值取決于函數(shù)調(diào)用的順序,而函數(shù)自身是任意順序進(jìn)行排列的,所以88,77都有可能,看哪個函數(shù)最后調(diào)用.

          這會導(dǎo)致很難debug,你必須要跟蹤整個程序的控制流程,這其實就引出了另外一個話題,全局變量有相關(guān)性,用全局變量來記憶狀態(tài)信息太復(fù)雜,最后是通過面向?qū)ο蟮姆椒?,用類進(jìn)行封裝.

          本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
          打開APP,閱讀全文并永久保存 查看更多類似文章
          猜你喜歡
          類似文章
          【2020Python修煉記 】Python語法入門--名稱空間
          給妹子講python-S01E18初探函數(shù)作用域
          python基礎(chǔ)7(函數(shù) Ⅱ)
          python的名稱空間和作用域
          python基礎(chǔ)-函數(shù)作用域
          全菊變量和菊部變量
          更多類似文章 >>
          生活服務(wù)
          分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
          綁定賬號成功
          后續(xù)可登錄賬號暢享VIP特權(quán)!
          如果VIP功能使用有故障,
          可點擊這里聯(lián)系客服!

          聯(lián)系客服