初學代碼時總有一個問題困擾我:a = 10 ? ? ? # a指向地址0x1234(存儲10)
變量a的值10存儲在0x1234,那么變量a需要存儲嗎?a又存儲在什么地址呢
目錄
1. ??命名空間的本質??
2. ??命名空間的內存占用??
3. ??變量名 vs 變量值的存儲對比??
4. ??靜態語言(如C)的對比??
5. ??為什么需要命名空間???
6. ??總結??
7.小測試
1. ??命名空間的本質??
- ??動態語言(如Python)??:
變量名與值的綁定關系通過 ??命名空間字典??(如globals()
)維護,但這個字典本身是一個 ??運行時動態創建的對象??,存儲在內存中。- ??變量名
"a"
??:作為字典的 ??鍵(Key)??(字符串對象)存儲。 - ??變量值
10
??:作為字典的 ??值(Value)??(指向實際對象的引用)。
- ??變量名
# 偽代碼展示Python內部實現(簡化版)
global_namespace = {"a": 0x1234, # 鍵是字符串"a",值是對象10的地址"b": 0x5678 # 其他變量...
}
2. ??命名空間的內存占用??
- ??存儲位置??:
命名空間字典本身是一個 ??堆內存中的對象??,有獨立的內存地址(可通過id(globals())
查看)。print(hex(id(globals()))) # 輸出如0x55a1b2d3e0(命名空間字典的地址)
- ??內存消耗??:
- 每個鍵(變量名)作為字符串對象存儲,占用內存。
- 每個值(變量引用)是指針(通常8字節,64位系統)。
- 字典的哈希表結構還有額外開銷(如哈希桶、沖突處理)。
3. ??變量名 vs 變量值的存儲對比??
??存儲內容?? | ??存儲位置?? | ??示例(Python)?? |
---|---|---|
??變量名 "a" ?? | 命名空間字典的鍵(堆內存) | globals()["a"] 中的 "a" |
??變量值 10 ?? | 獨立對象(堆內存) | id(a) 返回的地址(如 0x1234 ) |
??命名空間字典?? | 堆內存中的對象 | id(globals()) 返回的地址(如 0x55a1b2d3e0 ) |
4. ??靜態語言(如C)的對比??
- ??無運行時命名空間??:
變量名在編譯后直接替換為固定內存地址,不占用運行時內存。int a = 10; // 編譯后,所有對a的訪問變為對地址0x1000的操作
- ??無字典開銷??:
變量名僅在源碼和符號表中存在,編譯后的二進制文件中無痕跡。
5. ??為什么需要命名空間???
- ??動態語言的靈活性??:
Python 允許運行時動態添加/刪除變量(如globals()["x"] = 100
),必須維護變量名與值的映射關系。 - ??作用域管理??:
每個函數有獨立的locals()
字典,實現變量隔離。
6. ??總結??
- ??變量名存儲??:作為字符串鍵存在于命名空間字典中(堆內存)。
- ??命名空間存儲??:字典對象本身占用內存(地址可通過
id(globals())
獲取)。 - ??核心區別??:
- ??靜態語言??:變量名是編譯期概念,無運行時存儲。
- ??動態語言??:變量名是運行時對象,需內存存儲以支持動態特性。
7.小測試
- 多個變量的值相同的情況下,內存空間里是如何存儲的?(答案在下期)
- 舉例:a=b=c=10
這種設計是 Python 等動態語言靈活性的代價——犧牲部分內存和速度換取開發便捷性。
元寶老師提供標準化答案,解釋權歸迪普斯克老師,侵刪~