python如何將變數名轉化為同名字元串?

比如

import numpy as np

f3 = np.array([1, 2, 3])

f = ["f1", "f2"]

我的目的是把f3直接append到f裡面變成["f1", "f2", "f3"]。

C語言是靜態語言,有#define STR(s) #s的語法,那麼對於python呢,有沒有取巧的辦法啊?坐等各位解答。


你換個思路,不要傳變數,直接傳變數名就好了啊,從變數名獲取變數值是比較快速高效的

import sys

def append(list_, name):
list_.append((name, sys._getframe().f_back.f_locals[name]))

&>&>&> mylist = []
&>&>&> myvar = 12
&>&>&> append(mylist, "myvar")
&>&>&> mylist
[("myvar", 12)]

還是衷心希望你不要這麼干,變數名在Python當中是比較沒有意義的東西。如果覺得名字很有意義,最開始就寫成dict就好了:

myvalues = {"f1": 1, "f2": 2, "f3": 3}

啊,剛想起來,還有一個特別Pythonic的方法,用keyword argument嘛:

def add_parameters(params, **kwargs):
params.update(kwargs)

&>&>&> params = {}
&>&>&> add_parameters(params, f1 = 1, f2 = 3, f3 = 9)
&>&>&> params
{"f1": 1, "f2": 3, "f3": 9}

這不比你整那些沒用的強多了……


import inspect, re

def varname(p):
for line in inspect.getframeinfo(inspect.currentframe().f_back)[3]:
m = re.search(r"varnames*(s*([A-Za-z_][A-Za-z0-9_]*)s*)", line)
if m:
return m.group(1)

if __name__ == "__main__":
shit = 233
print varname(shit)

一個略蛋疼又很雞賊的方法。貌似是以前在stackoverflow上看到的。鏈接找不到了。

原理是,調用這個函數之後,回溯出來找到調用這個函數的那一行代碼(一個字元串),然後在這行代碼里找到所需的變數名。

Update: 找到鏈接了:http://stackoverflow.com/questions/592746/how-can-you-print-a-variable-name-in-python


import numpy as np

f3 = np.array([1, 2, 3])

f = ["f1", "f2"]

f.extend([k for k,v in list(locals().items()) if v is f3])


import re
import traceback

pattren = re.compile(r"[W+w+]*?get_variable_name((w+))")
__get_variable_name__ = []
def get_variable_name(x):
global __get_variable_name__
if not __get_variable_name__:
__get_variable_name__ = pattren.findall(traceback.extract_stack(limit=2)[0][3])
return __get_variable_name__.pop(0)

a = 1
b = a
c = b

print get_variable_name(a)
print get_variable_name(b)
print get_variable_name(c)
print [get_variable_name(a), get_variable_name(b), get_variable_name(c)]

# 粗暴的修正了:在同一行如果出現多次get_variable_name調用,出現錯誤結果的問題
# 這樣方法非常的dirty, 如果一行有多次調用,能知道調用的是哪一次就好了,請答友賜教!


sympy這個符號演算庫都要這樣寫

x = symbol("x")

即讓無數人崩潰的同一個名字寫兩遍。按說符號演算是最需要這個機制的,都沒有試圖做到這一點,說明Python沒有試圖提供這個特性,而這是為了維持引用透明性(用過R語言的都知道放棄引用透明性去省幾個符號有多坑爹),那些奇技淫巧都是與語言鬥爭的例子,感覺沒什麼意義。


貼一個老司機的解決方案,說是速度最優解,大家感受下。。。
vk = {}
shit = { 1:2, 2:3 }
aa = [2, 3, 4]
p_locals = locals().copy()
for k,v in p_locals.items():
vk[ id(v) ] = k

def var_name(p, vk):
return vk[ id(p) ]

print(var_name(shit, vk))

各位如果是Python2.x的話把items改成iteritems。
@Luau Lawrence


stackoverflow 既視感。

import insepct
def retrieve_name(var):
"""
utils:
get back the name of variables
"""
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]


Python 有一個函數globals() 或者locals()可以給出所有變數 {變數名:變數值} 組成的字典。

所以可以用:

variable = "value"
variable_name = globals().keys()[locals().values().index(variable)]

print variable_name

輸出就是

variable

這個方法跟 @陳不機智 的相似,都是在dict中找到對應value的key

但是這種方法存在一個問題,就是當前的變數中不能出現變數值一樣的兩個變數,比如:

variable = "value"
another_variable = "value"
variable_name = globals().keys()[locals().values().index(variable)]

print variable_name

輸出就是:

another_variable

這是因為list.index()只返回找到的第一個值所在的位置。

所以我感覺上述方法在python裡面很難解決這個問題 (希望有大神能提供一種方法避免上述問題)。

不知道樓主想要實現什麼功能,不過Python裡面有另外一個魔性的函數eval(), (MATLAB也有,很好用^_^),例子如下:

variable = 10
variable_name = "variable"

print eval(variable_name)
print eval(variable_name+" + "+variable_name)

輸出就是:

10

20

樓主可以在程序裡面自己添加一個list,記錄需要的變數名,不知道有沒有對樓主想實現的功能有幫助


&>&>&> a="123"

&>&>&> vname = lambda v,nms: [ vn for vn in nms if id(v)==id(nms[vn])][0]

&>&>&> vname(a, locals())

"a"


變成字典再取key 如何?


推薦閱讀:

你怎麼看待現在的 QQ 群?它有哪些痛點?
電腦上的麥克和耳機插孔為什麼不像手機一樣是一個,而是兩個插孔?
為什麼大城市的一些學生會離開家鄉上大學?
3.5mm 耳機插孔可以傳輸什麼信息?
這 10 年來電腦廠家都做了什麼?為什麼我在 2015 年使用 2007 年的筆記本完全沒有障礙?

TAG:Python | 編程 | 信息技術IT |