Я хотел бы смочь получить название переменной как строка, но я не знаю, имеет ли Python так много возможностей самоанализа. Что-то как:
>>> print(my_var.__name__)
'my_var'
Я хочу сделать это, потому что у меня есть набор переменных, как которые я хотел бы превратиться в словарь:
bar = True
foo = False
>>> my_dict = dict(bar=bar, foo=foo)
>>> print my_dict
{'foo': False, 'bar': True}
Но я хотел бы что-то более автоматическое, чем это.
Python имеет locals()
и vars()
, таким образом, я предполагаю, что существует путь.
Вы пытаетесь сделать это?
dict( (name,eval(name)) for name in ['some','list','of','vars'] )
Пример
>>> some= 1
>>> list= 2
>>> of= 3
>>> vars= 4
>>> dict( (name,eval(name)) for name in ['some','list','of','vars'] )
{'list': 2, 'some': 1, 'vars': 4, 'of': 3}
Как сказано в размотке, на самом деле это не то, что вы делаете в Python - переменные на самом деле являются отображением имен объектам.
Однако , вот один из способов сделать это:
>>> a = 1
>>> for k, v in list(locals().iteritems()):
if v is a:
a_as_str = k
>>> a_as_str
a
>>> type(a_as_str)
'str'
Это хак. Он не будет работать на всех дистрибутивах реализаций Python (в частности, на тех, которые не имеют traceback.extract_stack
.)
import traceback
def make_dict(*expr):
(filename,line_number,function_name,text)=traceback.extract_stack()[-2]
begin=text.find('make_dict(')+len('make_dict(')
end=text.find(')',begin)
text=[name.strip() for name in text[begin:end].split(',')]
return dict(zip(text,expr))
bar=True
foo=False
print(make_dict(bar,foo))
# {'foo': False, 'bar': True}
Обратите внимание, что этот хак хрупок:
make_dict(bar,
foo)
(вызов make_dict на 2 строки) не будет работать.
Вместо того, чтобы пытаться сгенерировать dict из значений foo
и bar
,
было бы гораздо питоничнее сгенерировать дикт из строк имен переменных 'foo'
и 'bar'
:
dict([(name,locals()[name]) for name in ('foo','bar')])
Это невозможно в Python, в котором действительно нет "переменных". В Python есть имена, и для одного и того же объекта может быть более одного имени.
У большинства объектов нет атрибута __ name __ . (Классы, функции и модули имеют; какие-либо еще встроенные типы, у которых он есть?)
Что еще вы ожидаете от print (my_var .__ name __)
кроме print ("my_var")
? Можете ли вы просто использовать строку напрямую?
Вы можете «разрезать» словарный запас:
def dict_slice(D, keys, default=None):
return dict((k, D.get(k, default)) for k in keys)
print dict_slice(locals(), ["foo", "bar"])
# or use set literal syntax if you have a recent enough version:
print dict_slice(locals(), {"foo", "bar"})
Альтернативно:
throw = object() # sentinel
def dict_slice(D, keys, default=throw):
def get(k):
v = D.get(k, throw)
if v is not throw:
return v
if default is throw:
raise KeyError(k)
return default
return dict((k, get(k)) for k in keys)