python变量名称的规定_Python 趣闻:如何获得变量的名字?
獲取變量名
今天我們探討Python中一個看似很簡單,實則并不容易的問題。這個問題是:如何獲得變量的名字?
舉例說明,給定一個變量var,給它賦值字符串"foo"。即
In [1]: var = "foo"
現在我們需要得到變量var的名字,即"var"。
嘗試下面兩種方法,我們得到的都是變量的值"foo",而不是變量的名字"var"。
In [2]: print var
foo
In [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編程中到底有沒有實際意義。這里,舉兩個小例子,說明"獲得變量名"的好處。
示例1
第一個例子是關于異常處理的。如果能夠得到變量名,那么Python異常的錯誤消息(Error Message)將變得更加有意義。例如:
1 first_num, second_num = 1, 2
2 if first_num != second_num:
----> 3 raise RuntimeError("%s is not equal to %s" % (first_num, second_num))
RuntimeError: 1 is not equal to 2
這里錯誤消息RuntimeError: 1 is not equal to 2的可讀性是比較差的,1和2分別是什么?我們需要結合源碼才能明白。假如能夠在Error Message中輸出1和2各自的變量名first_num和second_num,無疑是一件好事情。
示例2
第二個例子是基于一組變量創建字典。已知若干變量,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
def retrieve_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]] = i
print person
執行腳本,結果符合預期:
root@hzettv53:~# python test.py
{'gender': 'man', 'age': 21, 'name': 'bob', 'address': 'hangzhou'}
這種方案的基本思路是:通過inspect模塊的currentframe()方法得到一個包含調用者的所有局部變量的名字和值的列表,然后從列表中搜索變量值與目標值相同的元素,并返回該元素對應的變量名。
雖然這種方案在一些情況下能夠工作,但是其弊端是顯而易見的:1) 實現的復雜度較高 2) 如果存在多個變量值相同的情況,那么retrieve_name()函數將返回多個變量名,從而無法得到精確結果?;谶@兩點因素,這個方法中并沒有多大的實際應用意義。
總結
綜上所述,我們可以看到,Python編程中并不存在一種高效和可靠的方法去獲得變量名。所幸的是,盡管獲得變量名在某些場景下有好處,但是這種好處往往并不顯著,并且一般都存在替代方案。因此,盡管Python無法支持獲得變量名這一需求,但是日常的Python開發工作并不會因此受到多大影響。
最后,歡迎關注我的個人微信公眾號《測試不將就》,我們一起探討高質量軟件養成之道。
總結
以上是生活随笔為你收集整理的python变量名称的规定_Python 趣闻:如何获得变量的名字?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python搭建web服务器_Pytho
- 下一篇: python 时分秒毫秒_python将