Python globals() locals() vars() 三個內建函數的區別


在閱讀模塊源碼里, 常常看到 globals() locals() 的使用, 這兩個函數雖然可以從命名中

從外觀上知道不同, 但仍然不明白具體使用方式和實際的意義. 帶着好奇和疑問, 先看看

文檔和搜索相關的博客, 額外還了解到vars() 函數的信息, 在此帶着樣例代碼介紹.

首先參考官方文檔對這三個函數的介紹:

2. Built-in Functions – Python3.5

globals()

返回當前全局符號表, 通常在是返回當前模塊下的全局符號表, 比如全局內建的函數,

以及模塊里的全局符號(定義聲明的變量,類, 實例等), 在函數或者類方法中, globals()

返回的模塊符號表是其所在模塊, 而不是調用模塊.

locals() 更新並以字典形式返回當前局部符號表. 自由變量由函數塊的locals() 返回, 而

不會由 class 塊來返回. 需要注意的是, locals() 字典不應該被修改; 在解釋器中對修改行為

可能對 local 值或者自由變量無效.

vars() 返回 __dict__ 屬性, 比如模塊, 類, 實例, 或者其他 帶有 __dict__ 屬性的 object.

比如 模塊和實例擁有可更新的 __dict__ 屬性;然而其他 objects 可能會對 __dict__ 屬性

的寫操作限制(例如 類使用 dictproxy 阻止直接對字典更新).

vars() 如果不傳參數, 那么作用與 locals() 一樣. 需要注意的是, locals 字典只在讀操作

時使用, 因為對 locals 的更新會被忽略.

翻譯完相關文檔解釋后, 用代碼實驗:

#!/usr/bin/env python
# -*- coding: utf-8 -*- #   HELLO = 1   # GLOABLS 字典值包含 __builtins__, __doc__等通用的全局內建函數,模塊, # 以及剛才定義的 HELLO GLOABLS = globals()   LOCALS = locals()  # 此時與 globals() 是等價的!!   # globals 和 locals 此時是等價的, GLOBALS 和 LOCALS 其實是指向一個引用 LOCALS['B'] = 1       # VARS 的引用與 GLOABLS LOCALS 一樣, 可用 id() 來證實. VARS = vars()           class A(object):     # 此時的 locals 是 class 塊的 locals, 擁有 A_LOCALS A_GLOBALS 值     A_LOCALS = locals()         # 與 GLOBALS 等價     A_GLOBALS = globals()       def__init__(self):         self.func_locals = None         self.func_globals = None       deffunc(self):         self.func_locals = locals()         self.func_globals = globals()  #  即 GLOBALS 值   a = A() a.func()   a_vars = vars(a)  # 返回實例的 __dict__, 等價於 a_vars = a.__dict__ A_DICT = vars(A)  # 返回類的 dictproxy, 不能對其key直接操作賦值. a_vars['func_vars'] = "vars" print(a.func_vars)  # "vars"       

通過代碼驗證, 反過來理解文檔的解釋. 也明白了之前閱讀他人代碼使用的目的.

有另外一人寫的文章 Python Does What?!? 介紹了 dict 和 vars 的使用.

文中引用一篇 推特吐槽 , 原文是:

Most folks prefer len(s) to s.__len__(), prefer next(it) to it.next(),but forget to use vars(s) rather than s.__dict__

只能說明 vars 這個函數的命名並不是那么直觀, 而且已經有了 dict() 的定義, 也許設計者想出個 vars 命名來使用 233.

其他細節:

* 另外值得一提的是, 直接訪問實例 __dict__ 或者其他屬性, 比用內建函數訪問更高效.

* 在模塊里的全局作用域, 調試時會觀察到 gloabls() (以及等價的 locals())里的 key

是動態變化的. 那么隨着賦值給新變量名后, 字典會動態增加對應的 key.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM