欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python中的global和nonlocal關(guān)鍵字的使用場(chǎng)景分析

 更新時(shí)間:2025年09月18日 11:00:01   作者:請(qǐng)叫我技術(shù)官大人  
Python中g(shù)lobal和nonlocal用于處理變量作用域,本文給大家介紹Python中的global和nonlocal關(guān)鍵字的使用場(chǎng)景,感興趣的朋友跟隨小編一起看看吧

在 Python 中,globalnonlocal 關(guān)鍵字用于在函數(shù)內(nèi)部訪問(wèn)和修改外部作用域的變量。它們解決了函數(shù)內(nèi)部無(wú)法直接修改外部變量的問(wèn)題。

1. global 關(guān)鍵字

global 用于在函數(shù)內(nèi)部訪問(wèn)和修改全局作用域(模塊級(jí)別)的變量。

使用場(chǎng)景:

nonlocal 用于在嵌套函數(shù)中訪問(wèn)和修改外層(非全局)作用域的變量。

使用場(chǎng)景:

2. nonlocal 關(guān)鍵字

  • 當(dāng)需要在函數(shù)內(nèi)部修改全局變量時(shí)
  • 當(dāng)需要在函數(shù)內(nèi)部創(chuàng)建新的全局變量時(shí)
# 全局變量
count = 0
def increment():
    # 聲明 count 是全局變量
    global count
    count += 1
    print(f"函數(shù)內(nèi)部: count = {count}")
print(f"函數(shù)調(diào)用前: count = {count}")  # 輸出: 函數(shù)調(diào)用前: count = 0
increment()  # 輸出: 函數(shù)內(nèi)部: count = 1
print(f"函數(shù)調(diào)用后: count = {count}")  # 輸出: 函數(shù)調(diào)用后: count = 1
# 在函數(shù)內(nèi)部創(chuàng)建全局變量
def create_global():
    global new_var
    new_var = "我是全局變量"
create_global()
print(new_var)  # 輸出: 我是全局變量

注意事項(xiàng):

  • 在函數(shù)內(nèi)部讀取全局變量時(shí),不需要使用 global 關(guān)鍵字
  • 只有在修改全局變量時(shí)才需要使用 global
  • 使用 global 聲明后,對(duì)該變量的所有操作都會(huì)影響全局變量
  • 在閉包中修改外層函數(shù)的變量
  • 在多層嵌套函數(shù)中修改非全局的外部變量

nonlocal 用于在嵌套函數(shù)中訪問(wèn)和修改外層(非全局)作用域的變量。

使用場(chǎng)景:

  • 在閉包中修改外層函數(shù)的變量
  • 在多層嵌套函數(shù)中修改非全局的外部變量
def outer():
    # 外層函數(shù)變量
    counter = 0
    message = "原始消息"
    def inner():
        # 聲明 counter 是外層函數(shù)的變量
        nonlocal counter, message
        counter += 1
        message = f"修改后的消息 (計(jì)數(shù): {counter})"
        print(f"內(nèi)部函數(shù): counter = {counter}")
    print(f"調(diào)用inner前: counter = {counter}, message = '{message}'")
    inner()  # 輸出: 內(nèi)部函數(shù): counter = 1
    print(f"調(diào)用inner后: counter = {counter}, message = '{message}'")
    return counter, message
result = outer()
# 輸出:
# 調(diào)用inner前: counter = 0, message = '原始消息'
# 內(nèi)部函數(shù): counter = 1
# 調(diào)用inner后: counter = 1, message = '修改后的消息 (計(jì)數(shù): 1)'
print(f"外部獲取: counter = {result[0]}, message = '{result[1]}'")

多層嵌套示例:

def outer():
    x = "outer"
    def middle():
        nonlocal x
        x = "middle"
        def inner():
            nonlocal x
            x = "inner"
            print(f"最內(nèi)層: x = {x}")
        inner()
        print(f"中間層: x = {x}")
    middle()
    print(f"最外層: x = {x}")
outer()
# 輸出:
# 最內(nèi)層: x = inner
# 中間層: x = inner
# 最外層: x = inner

注意事項(xiàng):

  • nonlocal 只能用于嵌套函數(shù)中
  • 變量必須在外層函數(shù)中已定義,否則會(huì)引發(fā) SyntaxError
  • 不能用于全局作用域(使用 global 替代)
  • 在多層嵌套中,nonlocal 會(huì)向上查找最近的外層變量

3. global 與 nonlocal 的區(qū)別

特性globalnonlocal
作用域全局作用域(模塊級(jí)別)外層非全局作用域
使用位置任何函數(shù)中僅在嵌套函數(shù)中
變量要求變量可以不存在變量必須在外層已定義
創(chuàng)建變量可以創(chuàng)建新的全局變量不能創(chuàng)建新變量
查找范圍全局命名空間最近的封閉作用域

4. 常見(jiàn)錯(cuò)誤及解決方法

錯(cuò)誤1:未聲明直接修改

x = 10
def func():
    x += 1  # UnboundLocalError
func()

解決方法:使用 global 聲明

x = 10
def func():
    global x
    x += 1

錯(cuò)誤2:nonlocal 變量未定義

def outer():
    def inner():
        nonlocal x  # SyntaxError: no binding for nonlocal 'x' found
        x = 20
    inner()

解決方法:確保外層函數(shù)中已定義該變量

def outer():
    x = 10
    def inner():
        nonlocal x
        x = 20
    inner()

錯(cuò)誤3:混淆 global 和 nonlocal

x = 100
def outer():
    x = 10
    def inner():
        global x  # 錯(cuò)誤地使用了 global
        x = 20    # 修改的是全局 x,而不是 outer 的 x
    inner()
    print("outer x:", x)  # 輸出 10,而不是 20
outer()
print("global x:", x)  # 輸出 20

解決方法:正確使用 nonlocal

x = 100
def outer():
    x = 10
    def inner():
        nonlocal x  # 正確聲明
        x = 20
    inner()
    print("outer x:", x)  # 輸出 20
outer()
print("global x:", x)  # 輸出 100

5. 最佳實(shí)踐

  • 盡量避免使用全局變量:全局變量使代碼難以維護(hù)和理解,考慮使用類(lèi)或函數(shù)返回值替代
  • 優(yōu)先使用返回值:盡量通過(guò)函數(shù)返回值傳遞結(jié)果,而不是直接修改外部變量
  • 限制使用范圍:當(dāng)必須修改外部狀態(tài)時(shí),明確使用 globalnonlocal 并添加注釋
  • 命名區(qū)分:全局變量使用全大寫(xiě)命名(如 GLOBAL_VAR)以提高可讀性
  • 閉包替代全局變量:對(duì)于需要保持狀態(tài)的場(chǎng)景,使用閉包比全局變量更安全
# 使用閉包替代全局變量的示例
def create_counter():
    count = 0
    def counter():
        nonlocal count
        count += 1
        return count
    return counter
counter1 = create_counter()
print(counter1())  # 1
print(counter1())  # 2
counter2 = create_counter()
print(counter2())  # 1

總結(jié)

globalnonlocal 是 Python 中處理變量作用域的重要關(guān)鍵字:

  • global 用于在函數(shù)中訪問(wèn)和修改全局變量
  • nonlocal 用于在嵌套函數(shù)中訪問(wèn)和修改外層函數(shù)的變量

正確理解和使用這兩個(gè)關(guān)鍵字,可以幫助你編寫(xiě)更靈活的函數(shù)和閉包,同時(shí)避免常見(jiàn)的變量作用域錯(cuò)誤。在實(shí)際編程中,應(yīng)當(dāng)謹(jǐn)慎使用這些關(guān)鍵字,優(yōu)先考慮通過(guò)函數(shù)參數(shù)和返回值來(lái)傳遞數(shù)據(jù)。

關(guān)于id()函數(shù)有趣的問(wèn)題:

def outer():
    # 外層函數(shù)變量
    counter = 0
    message = "原始消息"
    print(id(counter))
    def inner():
        # 聲明 counter 是外層函數(shù)的變量
        nonlocal counter, message
        counter += 1
        message = f"修改后的消息 (計(jì)數(shù): {counter})"
        print(f"內(nèi)部函數(shù): counter = {counter}")
    print(f"調(diào)用inner前: counter = {counter}, message = '{message}'")
    inner()  # 輸出: 內(nèi)部函數(shù): counter = 1
    print(f"調(diào)用inner后: counter = {counter}, message = '{message}'")
    print(id(counter))
    return counter, message
result = outer()
# 輸出:
# 調(diào)用inner前: counter = 0, message = '原始消息'
# 內(nèi)部函數(shù): counter = 1
# 調(diào)用inner后: counter = 1, message = '修改后的消息 (計(jì)數(shù): 1)'
print(f"外部獲取: counter = {result[0]}, message = '{result[1]}'")

我們?cè)趧偛诺拇a案例中兩處添加了print(id(counter)),雖然我們使用了nonlocal使用函數(shù)內(nèi)的變量counter,但是在兩條print(id(counter))輸出的結(jié)果并不一樣,這是為什么呢?

原因分析

  • 整數(shù)是不可變類(lèi)型
    • Python 中的整數(shù)(int)是不可變對(duì)象(immutable)
    • 當(dāng)你執(zhí)行counter += 1時(shí),實(shí)際上創(chuàng)建了一個(gè)新的整數(shù)對(duì)象,而不是修改原對(duì)象
  • 變量重新綁定
    • nonlocal counter確保inner中的counter指向outer中的同一個(gè)變量
    • 但當(dāng)執(zhí)行counter += 1時(shí),相當(dāng)于counter = counter + 1
    • 這會(huì)將outercounter變量重新綁定到一個(gè)新的整數(shù)對(duì)象
  • 內(nèi)存地址變化
    • 第一次打印時(shí),counter指向整數(shù)0的內(nèi)存地址
    • 執(zhí)行counter += 1后,變量指向整數(shù)1的內(nèi)存地址
    • 兩個(gè)不同的整數(shù)對(duì)象有不同的內(nèi)存地址
# 初始狀態(tài)
counter = 0  # 假設(shè)內(nèi)存地址為 0x1000
print(id(counter))  # 輸出 0x1000 (指向整數(shù)0)
# 執(zhí)行 counter += 1
# 實(shí)際發(fā)生的過(guò)程:
temp = counter + 1  # 創(chuàng)建新整數(shù)1,假設(shè)地址為 0x2000
counter = temp      # 變量重新綁定到新地址
print(id(counter))  # 輸出 0x2000 (指向整數(shù)1)

證明它們是同一個(gè)變量

雖然內(nèi)存地址不同,但它們確實(shí)是同一個(gè)變量名(在相同作用域中):

  • 變量名不變
    • 兩次打印都是訪問(wèn)outer作用域中的counter變量
    • 只是變量指向的值改變了
  • 作用域驗(yàn)證
    • inner函數(shù)中修改后,outer中訪問(wèn)到的值確實(shí)變?yōu)?code>1
    • 返回值也是修改后的值

對(duì)比:使用可變對(duì)象

如果我們使用可變對(duì)象(如列表),情況就不同了:

def outer():
    counter = [0]  # 使用列表
    print(id(counter))
    def inner():
        nonlocal counter
        counter[0] += 1  # 修改列表內(nèi)容,而不是重新綁定
    inner()
    print(id(counter))  # 相同的內(nèi)存地址
outer()

在這個(gè)例子中,兩次id(counter)輸出相同,因?yàn)椋?/p>

  • 列表是可變對(duì)象
  • 我們只修改了列表內(nèi)容,沒(méi)有重新綁定整個(gè)變量
  • 變量仍然指向同一個(gè)列表對(duì)象

關(guān)鍵結(jié)論

  • nonlocal保證你訪問(wèn)的是同一個(gè)變量(同一個(gè)作用域中的同名變量)
    • 當(dāng)操作不可變對(duì)象(如整數(shù)、字符串、元組)時(shí):
    • 任何"修改"實(shí)際上創(chuàng)建新對(duì)象
    • 變量被重新綁定到新對(duì)象
  • id()輸出會(huì)改變
    • 當(dāng)操作可變對(duì)象(如列表、字典、集合)時(shí):
    • 可以原地修改內(nèi)容
    • 變量保持綁定到同一對(duì)象
  • id()輸出不變

到此這篇關(guān)于Python中的global和nonlocal關(guān)鍵字的用法詳解的文章就介紹到這了,更多相關(guān)Python global和nonlocal用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python 數(shù)據(jù)處理庫(kù) pandas 入門(mén)教程基本操作

    Python 數(shù)據(jù)處理庫(kù) pandas 入門(mén)教程基本操作

    pandas是一個(gè)Python語(yǔ)言的軟件包,在我們使用Python語(yǔ)言進(jìn)行機(jī)器學(xué)習(xí)編程的時(shí)候,這是一個(gè)非常常用的基礎(chǔ)編程庫(kù)。本文是對(duì)Python 數(shù)據(jù)處理庫(kù) pandas 入門(mén)教程,非常不錯(cuò),感興趣的朋友一起看看吧
    2018-04-04
  • python之import機(jī)制詳解

    python之import機(jī)制詳解

    這篇文章主要介紹了python的import機(jī)制,需要的朋友可以參考下
    2014-07-07
  • 詳解python中靜態(tài)方法staticmethod用法

    詳解python中靜態(tài)方法staticmethod用法

    本文主要介紹了python中靜態(tài)方法staticmethod用法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Python自動(dòng)化短視頻生成腳本實(shí)現(xiàn)熱門(mén)視頻流水線生產(chǎn)

    Python自動(dòng)化短視頻生成腳本實(shí)現(xiàn)熱門(mén)視頻流水線生產(chǎn)

    有粉絲和說(shuō),最近在網(wǎng)上看到一些視頻營(yíng)銷(xiāo)號(hào)一天能發(fā)布幾百條短視頻, 感覺(jué)是批量生成的,能不能用Python做個(gè)自動(dòng)化短視頻生成腳本呢?今天就帶大家一起實(shí)現(xiàn)熱門(mén)視頻批量流水線生產(chǎn)
    2021-09-09
  • Python編程super應(yīng)用場(chǎng)景及示例解析

    Python編程super應(yīng)用場(chǎng)景及示例解析

    最近有粉絲向我咨詢super相關(guān)的問(wèn)題,說(shuō)網(wǎng)上搜索到的教程不夠通俗易懂,看了之后還是不太理解。所以在這里基于我自己的理解來(lái)講解一下super
    2021-10-10
  • 安裝完P(guān)ython包然后找不到模塊的解決步驟

    安裝完P(guān)ython包然后找不到模塊的解決步驟

    今天小編就為大家分享一篇安裝完P(guān)ython包然后找不到模塊的解決步驟,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-02-02
  • Python中的變量和數(shù)據(jù)類(lèi)型使用方式

    Python中的變量和數(shù)據(jù)類(lèi)型使用方式

    這篇文章主要介紹了Python中的變量和數(shù)據(jù)類(lèi)型使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Python利用PyAutoGUI輕松搞定圖片上傳

    Python利用PyAutoGUI輕松搞定圖片上傳

    PyAutoGUI作為一個(gè)GUI操作的神器,我們看到了它的操作都很簡(jiǎn)單,非常通俗易懂,基本上看到函數(shù)就能知道它的功效。本文將用它實(shí)現(xiàn)圖片上傳功能,感興趣的可以了解一下
    2022-09-09
  • Python模擬實(shí)現(xiàn)全功能貸款計(jì)算器

    Python模擬實(shí)現(xiàn)全功能貸款計(jì)算器

    在個(gè)人理財(cái)中,貸款計(jì)算器是一款非常實(shí)用的工具,本文將教你如何使用Python編寫(xiě)一個(gè)全功能的貸款計(jì)算器,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-12-12
  • python3 cvs將數(shù)據(jù)讀取為字典的方法

    python3 cvs將數(shù)據(jù)讀取為字典的方法

    今天小編就為大家分享一篇python3 cvs將數(shù)據(jù)讀取為字典的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-12-12

最新評(píng)論