日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

python nonlocal global 变量作用域

發(fā)布時(shí)間:2023/12/13 综合教程 32 生活家
生活随笔 收集整理的這篇文章主要介紹了 python nonlocal global 变量作用域 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

  之前在討論閉包的時(shí)候有提到:

Python會(huì)按LEGB的順序來(lái)搜索變量:

要說(shuō)明的是,這里的訪問(wèn)規(guī)則只對(duì)普通變量有效, 對(duì)象屬性的規(guī)則與這無(wú)關(guān)(簡(jiǎn)單地說(shuō),訪問(wèn)一個(gè)對(duì)象的屬性與此無(wú)關(guān))。

L. Local. 局部作用域,即函數(shù)中定義的變量(沒(méi)有用global聲明)
E. Enclosing. 嵌套的父級(jí)函數(shù)的局部作用域,即包含此函數(shù)的上級(jí)函數(shù)的局部作用域,比如上面的示例中的labmda所訪問(wèn)的x就在其父級(jí)函數(shù)test的局部作用域里。通常也叫non-local作用域。
G. Global(module). 在模塊級(jí)別定義的全局變量(如果需要在函數(shù)內(nèi)修改它,需要用global聲明)
B. Built-in. built-in模塊里面的變量,比如int, Exception等等

但此規(guī)則有一個(gè)重要的限制:

一個(gè)不在局部作用域里的變量默認(rèn)是只讀的,如果試圖為其綁定一個(gè)新的值, Python認(rèn)為是在當(dāng)前的局部作用域里創(chuàng)建一個(gè)新的變量

  如果確實(shí)要在一個(gè)函數(shù)里修改全局變量,Python提供了global關(guān)鍵字來(lái)聲明一個(gè)變量是全局變量,聲明以后就可以修改其值了。 然而global只能用來(lái)修改全局作用域里的變量,對(duì)于嵌套函數(shù)的情況無(wú)能為力,所以計(jì)數(shù)器的例子在Python 2.x中是無(wú)法實(shí)現(xiàn)的。
  然而在Python 3中,一個(gè)新的關(guān)鍵字nonlocal的產(chǎn)生解決了這個(gè)問(wèn)題

計(jì)數(shù)器:

def make_counter():
    count = 0
    def counter():
        nonlocal count
        count += 1
        return count
    return counter
    
def make_counter_test():
  mc = make_counter()
  print(mc())
  print(mc())
  print(mc())

也可以使用generator來(lái)實(shí)現(xiàn)類(lèi)似的計(jì)數(shù)器

def counter_generator():
    count = 0
    while True:
        count += 1
        yield count
    
def counter_generator_test():
  # below is for python 3.x and works well
  citer = counter_generator().__iter__()
  i = 0
  while(i < 3) : 
    print(citer.__next__())
    i+=1



而今天在segmentfault上看到這個(gè)問(wèn)題時(shí)卻沒(méi)有及時(shí)反應(yīng)過(guò)來(lái):

問(wèn)題:

這段代碼不用在函數(shù)中聲明global x就可以打印出x的值

x = 20
def getx():
    print x

getx()

那請(qǐng)問(wèn)在哪些情況下必須要使用global聲明全局變量?

以下是一個(gè)多線程的python代碼片段,其中的x,l都是全局變量,但在threadcode()函數(shù)中只聲明了global x沒(méi)有global l。完整的代碼是可以成功運(yùn)行,但是把global x注釋掉后就會(huì)報(bào)錯(cuò)。請(qǐng)問(wèn)這是為什么,Lock對(duì)象比較特殊嗎?


import threading, time, sys
x = 50
l = threading.Lock()

def threadcode():
    global x
    l.acquire()
    print 'Thread %s invoked.' % threading.currentThread().getName()
    try:
        print 'Thread %s running.' % threading.currentThread().getName()
        x = x + 50
        print 'Thread %s set x to %d.' % \
                (threading.currentThread().getName(), x)
    finally:
        l.release()
...
 

解答:
對(duì)于Python2而言,對(duì)于一個(gè)全局變量,你的函數(shù)里如果只使用到了它的值,而沒(méi)有對(duì)其賦值(指a = XXX這種寫(xiě)法)的話,就不需要聲明global。相反,如果你對(duì)其賦了值的話,那么你就需要聲明global。聲明global的話,就表示你是在向一個(gè)全局變量賦值,而不是在向一個(gè)局部變量賦值。

global關(guān)鍵字用來(lái)在函數(shù)或其他局部作用域中使用全局變量。但是如果不修改全局變量也可以不使用global關(guān)鍵字。

nonlocal關(guān)鍵字用來(lái)在函數(shù)或其他作用域中使用外層(非全局)變量。






總結(jié)

以上是生活随笔為你收集整理的python nonlocal global 变量作用域的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。