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

一文探索CPython的變量實(shí)現(xiàn)機(jī)制

 更新時(shí)間:2025年02月20日 08:18:11   作者:wang_yb  
在Python中,變量的使用看起來非常簡(jiǎn)單,然而,這種簡(jiǎn)單的賦值操作背后,CPython其實(shí)做了很多復(fù)雜的工作,下面我們就來一起探索一下吧

Python中,變量的使用看起來非常簡(jiǎn)單,例如 a = 10,s = "hello"等等。

然而,這種簡(jiǎn)單的賦值操作背后,CPython其實(shí)做了很多復(fù)雜的工作。

本文將通過一些簡(jiǎn)單易懂的代碼示例,一起探索Python變量背后的奧秘,讓我們對(duì)它的實(shí)現(xiàn)機(jī)制有更深一步的理解。

1. 變量到底是什么?

Python中,變量本質(zhì)上是一個(gè)名字到值的映射。

例如,當(dāng)你寫a = 1時(shí),a是一個(gè)名字,而1是一個(gè)值。

CPython會(huì)將這個(gè)名字關(guān)聯(lián)起來,以便你后續(xù)可以通過名字訪問這個(gè)。

a = 1
print(a)  # 輸出:1

這種映射關(guān)系是通過一個(gè)名為命名空間的結(jié)構(gòu)實(shí)現(xiàn)的。

命名空間是一個(gè)字典,其中的鍵是變量名,值是變量對(duì)應(yīng)的對(duì)象。

它的定義可參考CPython源碼中的Include/internal/pycore_frame.h文件。

typedef struct _PyInterpreterFrame {
    // 省略... ...
    PyObject *f_globals; /* Borrowed reference. Only valid if not on C stack */
    PyObject *f_builtins; /* Borrowed reference. Only valid if not on C stack */
    PyObject *f_locals; /* Strong reference, may be NULL. Only valid if not on C stack */
    // 省略... ...
}

其中,f_locals 保存局部變量映射,函數(shù)執(zhí)行時(shí),局部變量值存于此;

f_globals 用于全局變量,模塊級(jí)代碼塊執(zhí)行時(shí),f_globals 指向模塊全局命名空間字典;

f_builtins 關(guān)聯(lián)內(nèi)置命名空間。

2. 變量的底層實(shí)現(xiàn):字節(jié)碼

CPython在執(zhí)行代碼時(shí),會(huì)先將代碼編譯成字節(jié)碼,然后由虛擬機(jī)執(zhí)行這些字節(jié)碼。我們可以通過 dis 模塊查看代碼的字節(jié)碼。

例如,對(duì)于a = 1,字節(jié)碼如下:

import dis

code = """
a = b
"""
dis.dis(code)

  • LOAD_NAME:從命名空間中加載變量b的值
  • STORE_NAME:將值存儲(chǔ)到變量a

這兩個(gè)指令展示了CPython如何處理變量的讀取和賦值。

3. 命名空間與作用域

Python中的變量存儲(chǔ)在不同的命名空間中,而這些命名空間又與代碼的作用域相關(guān),作用域決定了變量的可見性。

Python有三種主要的作用域:

  • 局部作用域:函數(shù)內(nèi)部的變量
  • 全局作用域:模塊級(jí)別的變量
  • 內(nèi)置作用域:包含內(nèi)置函數(shù)和類型的命名空間
x = "global"  # 全局變量

def func():
    y = "local"  # 局部變量
    print(x)  # 輸出:global
    print(y)  # 輸出:local

func()

在這個(gè)例子中,x是全局變量,y是局部變量。

如果在函數(shù)中嘗試訪問一個(gè)未定義的變量,CPython會(huì)按照以下順序查找:

  • 局部命名空間(f_locals
  • 全局命名空間(f_globals
  • 內(nèi)置命名空間(f_builtins

如果仍然找不到,就會(huì)拋出NameError異常。

4. 不同變量的字節(jié)碼

CPython為不同作用域的變量提供了不同的字節(jié)碼指令,以優(yōu)化性能和實(shí)現(xiàn)特定的行為。

4.1. 局部變量

在函數(shù)中,局部變量使用LOAD_FASTSTORE_FAST指令。

這些指令直接操作一個(gè)數(shù)組,而不是字典,因此速度更快。

def func():
    a = 1  # STORE_FAST
    b = a  # LOAD_FAST
    return b

dis.dis(func)

4.2. 全局變量

全局變量使用LOAD_GLOBALSTORE_GLOBAL指令。

這些指令會(huì)直接操作全局命名空間。

x = 1

def func():
    global x
    x = 2  # STORE_GLOBAL
    return x  # LOAD_GLOBAL

dis.dis(func)

4.3. 閉包變量

當(dāng)函數(shù)嵌套時(shí),內(nèi)部函數(shù)可以訪問外部函數(shù)的變量。

這些變量稱為閉包變量,使用LOAD_DEREFSTORE_DEREF指令。

def outer():
    x = 1
    def inner():
        return x  # LOAD_DEREF
    return inner

dis.dis(outer)

5. 類中的變量

在類定義中,變量的行為與函數(shù)不同。

類定義中的變量使用LOAD_NAMESTORE_NAME指令,因?yàn)轭惖拿臻g會(huì)動(dòng)態(tài)地與全局命名空間交互。

x = "global"

class MyClass:
    print(x)  # 使用 LOAD_NAME
    x = "local"
    print(x)  # 使用 LOAD_NAME

MyClass()

輸出:

查看指令的話,可以使用:python.exe -m dis .\cpython-variable.py命令。

如果在類中使用嵌套函數(shù),CPython會(huì)使用LOAD_CLASSDEREF指令來處理閉包變量。

class MyClass:
    x = "cell"
    def method(self):
        print(x)  # 使用 LOAD_CLASSDEREF

MyClass().method()

6. 編譯器如何選擇指令

CPython的編譯器會(huì)根據(jù)變量的作用域和代碼塊類型選擇合適的字節(jié)碼指令。

例如:

  • 如果變量是局部變量,編譯器會(huì)生成LOAD_FASTSTORE_FAST
  • 如果變量是全局變量,編譯器會(huì)生成LOAD_GLOBALSTORE_GLOBAL
  • 如果變量是閉包變量,編譯器會(huì)生成LOAD_DEREFSTORE_DEREF

7. 總結(jié)

Python變量的實(shí)現(xiàn)機(jī)制比看起來復(fù)雜得多,它涉及到字節(jié)碼指令、命名空間、作用域以及編譯器的決策邏輯。

通過理解這些概念,可以更好地掌握Python的變量行為,尤其是在復(fù)雜的作用域場(chǎng)景中。

如果對(duì)CPython的實(shí)現(xiàn)感興趣,可以進(jìn)一步閱讀其源碼中與變量相關(guān)的部分。

以上就是一文探索CPython的變量實(shí)現(xiàn)機(jī)制的詳細(xì)內(nèi)容,更多關(guān)于CPython變量的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python 自制簡(jiǎn)單版《我的世界》的詳細(xì)過程

    Python 自制簡(jiǎn)單版《我的世界》的詳細(xì)過程

    這篇文章主要介紹了教你用 Python 自制簡(jiǎn)單版《我的世界》,接下來,我們就帶你運(yùn)行這個(gè)項(xiàng)目,并對(duì)這個(gè)開源的小游戲做一下簡(jiǎn)單的更改,讓它變成“你的”世界
    2021-11-11
  • Python爬蟲抓取論壇關(guān)鍵字過程解析

    Python爬蟲抓取論壇關(guān)鍵字過程解析

    這篇文章主要介紹了Python爬蟲抓取論壇關(guān)鍵字過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Python中運(yùn)行并行任務(wù)技巧

    Python中運(yùn)行并行任務(wù)技巧

    這篇文章主要介紹了Python中運(yùn)行并行任務(wù)技巧,本文給出了兩個(gè)示例,并用map來處理并行任務(wù),需要的朋友可以參考下
    2015-02-02
  • Python3中的真除和Floor除法用法分析

    Python3中的真除和Floor除法用法分析

    這篇文章主要介紹了Python3中的真除和Floor除法用法,結(jié)合實(shí)例形式分析了真除與Floor除法的區(qū)別與使用技巧,需要的朋友可以參考下
    2016-03-03
  • Python應(yīng)用領(lǐng)域和就業(yè)形勢(shì)分析總結(jié)

    Python應(yīng)用領(lǐng)域和就業(yè)形勢(shì)分析總結(jié)

    在本篇文章總我們給大家整理了關(guān)于Python應(yīng)用領(lǐng)域和就業(yè)形勢(shì)分析以及圖文介紹,需要的朋友們可以參考下。
    2019-05-05
  • 使用PyTorch處理多維特征輸入數(shù)據(jù)的完美實(shí)現(xiàn)

    使用PyTorch處理多維特征輸入數(shù)據(jù)的完美實(shí)現(xiàn)

    在機(jī)器學(xué)習(xí)和深度學(xué)習(xí)領(lǐng)域,我們經(jīng)常會(huì)面對(duì)具有多維特征輸入的問題,這種情況出現(xiàn)在各種應(yīng)用中,包括圖像識(shí)別、自然語言處理、時(shí)間序列分析等,PyTorch是一個(gè)強(qiáng)大的深度學(xué)習(xí)框架,在本篇博客中,我們將探討如何使用PyTorch來處理多維特征輸入數(shù)據(jù)
    2023-10-10
  • python 生成任意形狀的凸包圖代碼

    python 生成任意形狀的凸包圖代碼

    這篇文章主要介紹了python 生成任意形狀的凸包圖代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04
  • python獲取當(dāng)前目錄路徑和上級(jí)路徑的實(shí)例

    python獲取當(dāng)前目錄路徑和上級(jí)路徑的實(shí)例

    下面小編就為大家分享一篇python獲取當(dāng)前目錄路徑和上級(jí)路徑的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • Python 迭代器工具包【推薦】

    Python 迭代器工具包【推薦】

    迭代器工具在產(chǎn)生數(shù)據(jù)的時(shí)候?qū)?huì)顯得非常便捷、高效,掌握了這些基本的方法之后,通過簡(jiǎn)單的組合就可以獲得更多迭代器工具。
    2016-05-05
  • python multiply()與dot使用示例講解

    python multiply()與dot使用示例講解

    這篇文章主要介紹了python multiply()與dot使用示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-12-12

最新評(píng)論