今天我們**python中乙個看似很簡單,實則並不容易的問題。這個問題是:如何獲得變數的名字?
舉例說明,給定乙個變數var
,給它賦值字串"foo"。即
in [1]
: var =
"foo"
現在我們需要得到變數var
的名字,即"var"。
嘗試下面兩種方法,我們得到的都是變數的值"foo",而不是變數的名字"var"。
in [2]
:print var
fooin [3]
:print
"%s"
% var
foo
怎麼辦呢?我們接著探索變數var
的全部屬性和方法:
in [4]
:print
dir(var)
['__add__'
,'__class__'
,'__contains__',.
..,'capitalize'
,'center',.
..]
經過嘗試後發現,在var
的71個(這個數字通過print len(dir(var))
得到)屬性和方法中,沒有乙個能夠讓我們得到var
的名字。
由此可見,得到變數值(value)容易,得到變數名(name)看起來十分困難。
在進一步探索其他方案之前,我們先看下"獲取變數名"在python程式設計中到底有沒有實際意義。這裡,舉兩個小例子,說明"獲得變數名"的好處。
第乙個例子是關於異常處理的。如果能夠得到變數名,那麼python異常的錯誤訊息(error message)將變得更加有意義。例如:
1 first_num, second_num =1,
22if first_num != second_num:--
-->
3raise runtimeerror(
"%s is not equal to %s"
%(first_num, second_num)
)runtimeerror:1is
not equal to 2
這裡錯誤訊息runtimeerror: 1 is not equal to 2
的可讀性是比較差的,1和2分別是什麼?我們需要結合原始碼才能明白。假如能夠在error message中輸出1和2各自的變數名first_num
和second_num
,無疑是一件好事情。
第二個例子是基於一組變數建立字典。已知若干變數,name, address, age, gender
,我們希望基於它們建立乙個字典person
。一般可以這樣實現:
person =
person[
"name"
]= name
person[
"address"
]= address
person[
"age"
]= age
person[
"gender"
]= gender
雖然這種實現完全可行,但是對於像我這樣有"潔癖"的python愛好者來說,有兩點覺得不舒服。一是變數的名字出現了重複;二是賦值語句(不管是=
賦值還是:
賦值)出現了重複。當變數數量越多時,重複情況就越多。
如果能夠使用類似下面這種迴圈來實現,**就能更加簡潔:
for i in
[name, address, age, gender]
: person[i]
= i # 由於i是變數值,因此不可行
以上兩個示例說明獲得變數名對於python程式設計是有好處的。
然而,在前文我們也看到了,得到python變數名是困難的。那麼,為什麼無法直接得到python變數名呢?查閱相關資料後發現,在python中,變數名字是物件(object)的單向(而不是雙向)引用。也就是說,根據變數名,能夠直接得到它所指向的物件;反之,根據物件,是無法得到指向它的變數名的。
之所以有這麼乙個規定,是基於成本考慮的。在程式中,往往存在大量的變數(整型,字串,列表,字典,布林…)。如果每乙個變數都需要有乙個包含指向它的變數名的列表,那麼這些列表的建立和維護的成本(實現成本,執行成本…)將變得難以承受。
既然直接方法不可行,那麼有沒有間接的方法呢?python的inspect
模組提供了一種間接方案。以示例2為例,基於inspect
的for迴圈實現為:
import inspect
defretrieve_name
(var)
: callers_local_vars = inspect.currentframe(
).f_back.f_locals.items(
)return
[var_name for var_name, var_val in callers_local_vars if var_val is var]
name, address, age, gender =
"bob"
,"hangzhou",21
,"man"
person =
for i in
[name, address, age, gender]
: person[retrieve_name(i)[0
]]= iprint person
執行指令碼,結果符合預期:
root@hzettv53:~# python test.py
這種方案的基本思路是:通過inspect
模組的currentframe()
方法得到乙個包含呼叫者的所有區域性變數的名字和值的列表,然後從列表中搜尋變數值與目標值相同的元素,並返回該元素對應的變數名。
雖然這種方案在一些情況下能夠工作,但是其弊端是顯而易見的:1) 實現的複雜度較高 2) 如果存在多個變數值相同的情況,那麼retrieve_name()函式將返回多個變數名,從而無法得到精確結果。基於這兩點因素,這個方法中並沒有多大的實際應用意義。
綜上所述,我們可以看到,python程式設計中並不存在一種高效和可靠的方法去獲得變數名。所幸的是,儘管獲得變數名在某些場景下有好處,但是這種好處往往並不顯著,並且一般都存在替代方案。因此,儘管python無法支援獲得變數名這一需求,但是日常的python開發工作並不會因此受到多大影響。
python建立變數名軟體 動態建立變數名
我有這段 來建立乙個介面和一些按鈕 maya中的python class mrshadowmapchangerui def init self smattrs shadowmap smapresolution smapsamples smapsoftness smapbias smniceattrs...
python有哪些變數名 python變數名有哪些
python 需要使用識別符號給變數命名,其實識別符號就是用於給程式中變數 類 方法命名的符號 簡單來說,識別符號就是合法的名字 python 語言的識別符號必須以字母 下畫線 開頭,後面可以跟任意數目的字母 數字和下畫線 此處的字母並不侷限於 26 個英文本母,可以包含中文字元 日文字元等。由於 ...
python注釋與變數名
python 一 再給計算機執行的同時也要給人 因此需要對 進行注釋 1 行注釋 只能在同一行進行注釋,用 注釋內容 2 多行注釋 可以跨多行進行注釋,用 注釋內容 或者 注釋內容 二 變數 1 變數含義 為方便資料的呼叫,對資料進行命名,可以理解為賦予乙個東西乙個名字。python中變數名對於變數...