Python之謎 如何獲取變數名?

2021-09-24 19:28:30 字數 3348 閱讀 1234

今天我們**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_numsecond_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中變數名對於變數...