별도의 변수 사전을 만드는 간단한 방법?


220

변수의 이름을 문자열로 얻을 수 있기를 원하지만 파이썬에 많은 내성 기능이 있는지 모르겠습니다. 다음과 같은 것 :

>>> print(my_var.__name__)
'my_var'

변수가 많기 때문에 다음과 같은 사전으로 바꾸고 싶습니다.

bar = True
foo = False
>>> my_dict = dict(bar=bar, foo=foo)
>>> print my_dict 
{'foo': False, 'bar': True}

그러나 나는 그것보다 더 자동적 인 것을 원합니다.

파이썬은이 locals()vars()나는 방법이 생각 때문에.


31
사람들이 요구 한 것에 대해 혼란스러워하는 것 같아서 흥미로운 질문이기 때문에 여기서 다시 설명하겠습니다. [foo, bar, baz] 배열이 주어지면 { 'foo': foo, 'bar': bar, 'baz': baz}와 같은 사전을 원하고 배열에 어떤 변수가 있는지 모릅니다. 그래서 질문자는 파이썬에서 변수의 이름을 문자열로 얻는 방법을 묻습니다. 이제 사람들은 끔찍한 응답을 탐색하여 왜 이것이 파이썬에서 실제로 좋은 아이디어가 아닌지 배우는 몇 곳을 찾을 수 있기를 바랍니다.
Jesse Sherlock


2
기술을 사용하는 한 가지 방법은 문자열 형식 지정 호출을 간소화하는 것입니다. '{var} {foo} {bar}'. format (** named (var, foo, bar)), 여기서 "named"는 dict ( 'var': var)에 설명 된대로
Gordon Bean

4
이름이 객체에 매핑되고 동일한 객체를 가리키는 여러 이름을 가질 수 있기 때문에 실제로는 나쁜 질문이라고 생각합니다. 그 매핑을 뒤집는 목표를 달성 할 필요가 없었습니다. 따라서 잘못된 답변이 여기에 허용된다는 사실은 의미가 없습니다 .Google 검색으로 인해 여기에 오면 분명히 잘못된 질문을합니다.
Aaron Hall

1
이것은 디버깅에 좋은 아이디어입니다!
john ktejik

답변:


48

이 작업을 시도하고 있습니까?

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}

1
rlotun은 이름을 발견 할 수 있기 때문에 초기 "정신"에 더 가깝습니다. 나는 당신의 대답을 모두 사용할 수 있습니다. 아니면 그냥 내 손을 사용하여 입력하십시오. 자동화 된 것이 아닌 것들도 있습니다.
e-satis

7
@ e-satis : @rlotun이 작동하려면 변수 목록을 제공해야합니다. 변수 목록이 있다면 이름을 "발견"하는 요점은 무엇입니까?
S.Lott

4
왜 명시 적으로 지역과 세계를 사용하는 대신 평가가 필요한가?

1
@Roger Pate : 전체 운동의 요점을 알 수 없었기 때문입니다.
S.Lott

242
이 답변은 묻는 질문에 대한 답변이 아닙니다. 변수 목록이 있다면 이름을 "발견"하는 요점은 무엇입니까? 대신 있도록 중복을 피하기 위해 print('x: ' + x)하나가 쓸 수 magic_print(x)두 번 변수의 이름을 작성하지 않고 동일한 출력을 가지고있다.
Piotr Dobrogost '

130

unwind가 말했듯이, 이것은 실제로 파이썬에서하는 것이 아닙니다. 변수는 실제로 객체에 대한 이름 매핑입니다.

그러나 시도하고 수행하는 한 가지 방법이 있습니다.

 >>> 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'

14
이 아이디어에는 장점이 있지만 두 변수 이름이 같은 값 (예 :)을 참조 True하면 의도하지 않은 변수 이름이 반환 될 수 있습니다.
unutbu

14
id(v) == id(a)대신에 v is a? int, 문자열 및 유사하게 구현 된 사용자 정의 유형과 같은 여러 변수에 바인딩 된 객체의 경우 실패합니다.

예, v is a더 나은 선택이 될 것입니다. 그리고 네, 발생할 수있는 모든 잠재적 함정을 감안할 때 확실히 위험합니다! ;-)
rlotun

16
@ e-satis 나는 rlotun이 이름을 발견 할 수 있기 때문에 rlotun이 그것의 초기 "정신"에 더 가깝다는 귀하의 의견에 동의 할 때이 답변을 답변으로 표시하지 않은 것에 놀랐습니다 . 또한 S.Lott의 답변으로 귀하의 질문에 전혀 답이되지 않습니다 ...
Piotr Dobrogost

2
"과도하고 위험한"... 그리고 eval을 사용하는 것이 아닌가요?
bug

63

나는 이것을 꽤 많이하고 싶었다. 이 핵은 rlotun의 제안과 매우 유사하지만 하나의 라이너로 나에게 중요합니다.

blah = 1
blah_name = [ k for k,v in locals().iteritems() if v is blah][0]

파이썬 3+

blah = 1
blah_name = [ k for k,v in locals().items() if v is blah][0]

3
@keflavich 나는이 접근법을 매우 좋아했으며 때때로 그것을 사용했습니다. 그러나 함수 내부에서 작동하도록 할 수 없습니다. "더 나은"방법이있을 것 같지만 nbubis가 생각하는 것만 큼 간단하지는 않습니다. keflavich 기능에서 사용할 수 있었습니까? 이것이 내가 이것에 대해 질문하는 곳입니다.
Leo

10
파이썬 3에서, 참고 iteritems()로 대체items()
조나단 휠러

신뢰할 수 없음 : spam = 1; blah = 1; blah_name = [ k for k,v in locals().items() if v is blah][0]; print(blah_name)출력spam
andreasdr

1
@andreasdr 때문 spam = 1, blah = 1; assert spam is blah입니다. 기본 데이터 유형을 비교할 때 솔루션이 중단됩니다.
JYun

17

이것은 해킹입니다. 모든 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)

(2 줄에 make_dict를 호출하면) 작동하지 않습니다.

대신의 DICT을 생성하기 위해 노력하는 foobar, 그것은 훨씬 더 파이썬은 문자열의 밖으로 DICT 생성하는 것이다 변수 이름 'foo''bar':

dict([(name,locals()[name]) for name in ('foo','bar')])

1
스마트 핵에 +1. 물론 추적은 매우 느리기 때문에 사용하기가 느려질 수 있습니다.
e-satis

1
+1111111 !!!! 응, 느리지 만 print("a_very_long_name: {}'.format(a_very_long_name))누가 신경 써서 교체 할 때 !
frnhr

14

실제로는 "변수"가없는 파이썬에서는 불가능합니다. Python에는 이름이 있으며 동일한 객체에 대해 둘 이상의 이름이있을 수 있습니다.


예, 저는 질문을 간단하게 만들었지 만 "get_var_tags (var) [0]"과 같은 것을 기대하고있었습니다.
e-satis

10

내 문제가이 질문이 왜 유용한 지 설명하는 데 도움이 될 것이며, 답변하는 방법에 대해 조금 더 통찰력을 줄 수도 있습니다. 내 코드의 다양한 변수에 대해 빠른 인라인 헤드 검사를 수행하는 작은 함수를 작성했습니다. 기본적으로 변수 이름, 데이터 유형, 크기 및 기타 속성이 나열되어 있으므로 실수를 신속하게 파악할 수 있습니다. 코드는 간단하다 :

def details(val):
  vn = val.__name__                 #  If such a thing existed
  vs = str(val)
  print("The Value of "+ str(vn) + " is " + vs)
  print("The data type of " + vn + " is " + str(type(val)))

따라서 복잡한 사전 / 목록 / 튜플 상황이있는 경우 통역사가 지정한 변수 이름을 반환하도록하는 것이 도움이됩니다. 예를 들어 다음은 이상한 사전입니다.

m = 'abracadabra'
mm=[]    
for n in m:
  mm.append(n)
mydic = {'first':(0,1,2,3,4,5,6),'second':mm,'third':np.arange(0.,10)}



details(mydic)

The Value of mydic is {'second': ['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a'], 'third': array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.]), 'first': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
The data type of mydic is <type 'dict'>

details(mydic['first'])
The Value of mydic['first'] is (0, 1, 2, 3, 4, 5, 6)]
The data type of mydic['first'] is <type 'list'>

details(mydic.keys())
The Value of mydic.keys() is ['second', 'third', 'first']
The data type of mydic.keys() is <type 'tuple'>

details(mydic['second'][0])
The Value of mydic['second'][0] is a
The data type of mydic['second'][0] is <type 'str'>

나는 이것을 올바른 장소에 넣었는지 확실하지 않지만 도움이 될 것이라고 생각했습니다. 나는 그것을 희망한다.


따라서 헤드 체크를 통해 변수 / 이름이 코드에서 다른 시간에 다른 것을 가리킬 수 있다는 사실을 설명합니까? 예를 들어 myconnection한 지점에서 부울 값을, 다른 시간에 정수를, 코드 실행의 다른 지점에서 소켓 연결을 가리킬 수 있습니까 ??

9

이 질문에 대한 답을 바탕으로 깔끔하고 유용한 기능을 작성했습니다. 유용 할 수 있도록 여기에 넣겠습니다.

def what(obj, callingLocals=locals()):
    """
    quick function to print name of input and value. 
    If not for the default-Valued callingLocals, the function would always
    get the name as "obj", which is not what I want.    
    """
    for k, v in list(callingLocals.items()):
         if v is obj:
            name = k
    print(name, "=", obj)

용법:

>> a = 4
>> what(a)
a = 4
>>|

6

이미 특정 값 목록이 있으면 @S가 설명하는 방식을 발견했습니다. 로트가 최고입니다. 그러나 아래 설명 된 방법은 원하는 경우 변수 이름을 제공 할 필요는 없지만 변수 이름을 제공 할 필요 없이 코드 전체에 추가 된 모든 변수와 클래스를 얻는 데 효과적 입니다. 클래스를 제외하도록 코드를 확장 할 수 있습니다.

import types
import math  # mainly showing that you could import what you will before d

# Everything after this counts
d = dict(globals())

def kv_test(k,v):
    return (k not in d and 
            k not in ['d','args'] and
            type(v) is not types.FunctionType)

def magic_print(*args):
    if len(args) == 0: 
        return {k:v for k,v in globals().iteritems() if kv_test(k,v)}
    else:
        return {k:v for k,v in magic_print().iteritems() if k in args}

if __name__ == '__main__':
    foo = 1
    bar = 2
    baz = 3
    print magic_print()
    print magic_print('foo')
    print magic_print('foo','bar')

산출:

{'baz': 3, 'foo': 1, 'bar': 2}
{'foo': 1}
{'foo': 1, 'bar': 2}

6

파이썬 3에서는 이것이 쉽습니다.

myVariable = 5
for v in locals():
  if id(v) == id("myVariable"):
    print(v, locals()[v])

이것은 인쇄됩니다 :

myVariable 5


이 rlotun의 접근 방식 만 조금 더 간단 유사하다
officialhopsof

10
-1. 새 통역사 창을 열고를 시도하십시오 for v in locals().
Air

무슨 말인지 모르겠어요?
officialhopsof

4
다음과 같은 오류가 발생합니다. RuntimeError : 반복하는 동안 사전 크기가 변경되었습니다 ...
Nizar B.

2
그러나 당신은 할 수 있습니다for v in list(locals()):
Phylliida

5

파이썬 3. inspect를 사용하여 호출 로컬 네임 스페이스를 캡처 한 다음 여기에 제시된 아이디어를 사용하십시오. 지적한대로 둘 이상의 답변을 반환 할 수 있습니다.

def varname(var):
  import inspect
  frame = inspect.currentframe()
  var_id = id(var)
  for name in frame.f_back.f_locals.keys():
    try:
      if id(eval(name)) == var_id:
        return(name)
    except:
      pass

좋은 대답이지만 나를 위해 더 나은 : ... id (eval (name, None, frame.f_back.f_locals)) == ...
Emmanuel DUMAS

5

변수 이름을 읽기 위해 만든 함수는 다음과 같습니다. 더 일반적이며 다른 응용 프로그램에서 사용할 수 있습니다.

def get_variable_name(*variable):
    '''gets string of variable name
    inputs
        variable (str)
    returns
        string
    '''
    if len(variable) != 1:
        raise Exception('len of variables inputed must be 1')
    try:
        return [k for k, v in locals().items() if v is variable[0]][0]
    except:
        return [k for k, v in globals().items() if v is variable[0]][0]

지정된 질문에 사용하려면

>>> foo = False
>>> bar = True
>>> my_dict = {get_variable_name(foo):foo, 
               get_variable_name(bar):bar}
>>> my_dict
{'bar': True, 'foo': False}

4

실을 읽을 때 나는 많은 마찰을 보았다. 잘못된 답변을 한 다음 누군가가 올바른 답변을 내릴 수있을 정도로 쉽습니다. 어쨌든, 여기 내가 찾은 것이 있습니다.

보낸 사람 : [effbot.org] ( http://effbot.org/zone/python-objects.htm#names )

이름은 약간 다릅니다. 실제로는 객체의 속성이 아니며, 객체 자체는 그 객체가 무엇인지 모릅니다.

객체는 여러 개의 이름을 갖거나 전혀 이름을 가질 수 없습니다.

이름은 네임 스페이스 (예 : 모듈 네임 스페이스, 인스턴스 네임 스페이스, 함수의 로컬 네임 스페이스)에 있습니다.

참고 : 그것은 객체 자체가 무엇이라고 불리는지를 알지 못한다고 말했기 때문에 이것이 단서였습니다. 파이썬 객체는 자기 참조가 아닙니다. 그런 다음 이름은 네임 스페이스에 있습니다. 우리는 이것을 TCL / TK에 있습니다. 아마도 내 대답이 도움이 될 것입니다 (그러나 도움이되었습니다)

    jj = 123
    인쇄 평가 ( " '"+ str (id (jj)) + "'")
    프린트 디렉토리 ()

166707048
[ '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'jj']

목록 끝에 'jj'가 있습니다.

코드를 다음과 같이 다시 작성하십시오.

    jj = 123
    인쇄 평가 ( " '"+ str (id (jj)) + "'")
    dir ()에서 x의 경우 :
        프린트 아이디 (eval (x))

161922920
[ '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'jj']
3077447796
136515736
3077408320
3077656800
136515736
161922920

이 불쾌한 코드 id는 변수 / 객체 / 무엇이든 당신이 호출하는 호출의 이름입니다.

그래서 거기에 있습니다. 'jj'의 메모리 주소는 전역 네임 스페이스에서 사전을 검색 할 때와 마찬가지로 직접 검색 할 때와 동일합니다. 이 기능을 수행 할 수 있다고 확신합니다. 변수 / 객체 / wypci가있는 네임 스페이스를 기억하십시오.

QED.


6
여기에 eval을 두 가지 미친 용도로 사용합니다. 첫 번째는 정확히 다음과 같습니다 print id(jj). 두 번째는 단순히 이름을 찾고보다 쉽게 ​​수행 할 수 있습니다 vars().
Ned Batchelder 1

2

어쩌면 나는 이것을 지나치게 생각하고 있지만 ..

str_l = next((k for k,v in locals().items() if id(l) == id(v)))


>>> bar = True
>>> foo = False
>>> my_dict=dict(bar=bar, foo=foo)
>>> next((k for k,v in locals().items() if id(bar) == id(v)))
'bar'
>>> next((k for k,v in locals().items() if id(foo) == id(v)))
'foo'
>>> next((k for k,v in locals().items() if id(my_dict) == id(v)))
'my_dict'

큰! 이것이 내가 찾던 것입니다. 감사합니다 @ rh0dium ... \ nvariable = 1 \n [k for k,v in locals().items() if id(variable) == id(v)] \n Out[14]: ['variable']
Majdi

2
import re
import traceback

pattren = re.compile(r'[\W+\w+]*get_variable_name\((\w+)\)')
def get_variable_name(x):
    return pattren.match( traceback.extract_stack(limit=2)[0][3]) .group(1)

a = 1
b = a
c = b
print get_variable_name(a)
print get_variable_name(b)
print get_variable_name(c)

2

pypi 솔루션을 업로드했습니다 . C #의 nameof기능 과 동등한 기능을 정의하는 모듈 입니다.

그것은 호출 된 프레임에 대한 바이트 코드 명령을 반복하여 전달 된 변수 / 속성의 이름을 얻습니다. 이름은 기능 이름 다음 .argreprLOAD나오는 지침 에서 찾을 수 있습니다.


2

나는 이런 종류의 마술을 강력하게하기 위해 패키지 마법 을 썼다 . 당신은 쓸 수 있습니다:

from sorcery import dict_of

my_dict = dict_of(foo, bar)

1

대부분의 객체에는 __name__ 속성 이 없습니다 . (클래스, 함수 및 모듈은 더 많은 내장 유형을 가지고 있습니까?)

당신을 위해 다른 무엇을 기대 print(my_var.__name__)이외의 print("my_var")? 간단히 문자열을 직접 사용할 수 있습니까?

당신은 dict을 "슬라이스"할 수 있습니다 :

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)

2
+1 그러나 이름 이 존재하지 않는다는 것을 알고 있습니다. 왜 모든 사람들이이 "무언가 같은 것"을 씁니까? 이름을 코딩하고 싶지 않기 때문에 솔루션이 문제를 해결하지 못합니다. 이미 질문에 이미 설명한 dict 솔루션을 수행합니다.
전자 좌석

3
@ e-satis : locals ()의 모든 것을 사용하여 문제를 해결한다면, 당신이 무엇을 요구하는지 전혀 모른다. 나는 전화로 당신에게있는 거 좋아 같은데요 some_func(var)내가 아주 멀리에서가 아니라 지적하려고, 그래서 some_func("var")함께, dictslice 한 번에 여러 변수의 이름 값의 매핑을 얻을 수 있도록.

1

글쎄, 나는 며칠 전에 똑같은 요구 를 겪었고 객체 자체를 가리키는 변수의 이름 얻어야했습니다 .

왜 그렇게 필요 했습니까?

요컨대 나는 Maya 용 플러그인을 만들고 있었다 . 핵심 플러그인은 C ++를 사용하여 빌드되었지만 GUI는 프로세서를 많이 사용하지 않고 Python을 통해 작성됩니다. 필자는 아직 returndefault 이외의 플러그인에서 여러 값을 얻는 방법을 모르기 MStatus때문에 파이썬에서 사전을 업데이트하려면 GUI를 구현하는 객체를 가리키는 변수의 이름을 전달해야했습니다. 플러그인에 대한 사전 자체를 포함하고를 사용하여 MayaMGlobal::executePythonCommand() 의 글로벌 범위에서 사전을 업데이트하십시오 .

내가 한 일을하는 것은 다음과 같습니다.

import time

class foo(bar):

    def __init__(self):
        super(foo, self).__init__()
        self.time = time.time() #almost guaranteed to be unique on a single computer

    def name(self):
        g = globals()
        for x in g:
            if isinstance(g[x], type(self)):
                if g[x].time == self.time:
                    return x
                    #or you could:
                    #return filter(None,[x if g[x].time == self.time else None for x in g if isinstance(g[x], type(self))])
                    #and return all keys pointing to object itself

globals많은 키 에서 완벽한 솔루션이 아니라는 것을 알고 있습니다 . 예를 들어 다음 과 같은 동일한 객체를 가리킬 수 있습니다 .

a = foo()
b = a
b.name()
>>>b
or
>>>a

접근 방식은 스레드로부터 안전하지 않습니다. 내가 틀렸다면 나를 바로 잡으십시오.

적어도이 접근법 은 객체 자체 를 가리키는 전역 범위의 변수 이름 을 가져 와서 내부적으로 사용하기 위해 인수로 플러그인에 전달 하여 내 문제를 해결 했습니다.

나는 이것을 int(기본 정수 클래스) 에서 시도했지만 문제는 이러한 기본 클래스가 무시되지 않는다는 것입니다 (잘못된 경우 사용 된 기술 용어를 수정하십시오). 다시 구현 int한 다음 수행 할 수 int = foo있지만 기본 요소 a = 3foo아닌 절대 대상은 아닙니다 . 당신이해야 할 것을 극복하기 위해 a = foo(3)얻기 위해 a.name()작업에.


1

파이썬 2.7 이상에서는 사전 이해력이있어 조금 더 짧아집니다. 가능하다면 나는 최고 답변 에서처럼 eval (eval is evil) 대신 getattr을 사용합니다. 자아는 당신이보고있는 맥락을 가진 어떤 물체 일 수 있습니다. 객체 또는 locals = locals () 등일 수 있습니다.

{name: getattr(self, name) for name in ['some', 'vars', 'here]}

1

나는 비슷한 문제를 겪고 있었다. @ S.Lott는 "변수 목록이 있다면 이름을"발견 "하는 요점은 무엇입니까?" 그리고 내 대답은 그것이 가능한지 여부와 어떤 이유로 변수를 유형별로 목록으로 정렬 하려는지 확인하는 것입니다. 어쨌든 내 연구 에서이 스레드를 발견했으며 솔루션은 약간 확장되어 @rlotun 솔루션을 기반으로합니다. @unutbu는 "이 아이디어에는 장점이 있지만 두 변수 이름이 같은 값 (예 : True)을 참조하면 의도하지 않은 변수 이름이 반환 될 수 있습니다." 이 연습에서는 사실이므로 각 가능성에 대해 이와 유사한 목록 이해를 사용하여 처리했습니다 isClass = [i for i in isClass if i != 'item']. 그렇지 않으면 "항목"이 각 목록에 나타납니다.

__metaclass__ = type

from types import *

class Class_1: pass
class Class_2: pass
list_1 = [1, 2, 3]
list_2 = ['dog', 'cat', 'bird']
tuple_1 = ('one', 'two', 'three')
tuple_2 = (1000, 2000, 3000)
dict_1 = {'one': 1, 'two': 2, 'three': 3}
dict_2 = {'dog': 'collie', 'cat': 'calico', 'bird': 'robin'}
x = 23
y = 29
pie = 3.14159
eee = 2.71828
house = 'single story'
cabin = 'cozy'

isClass = []; isList = []; isTuple = []; isDict = []; isInt = []; isFloat = []; isString = []; other = []

mixedDataTypes = [Class_1, list_1, tuple_1, dict_1, x, pie, house, Class_2, list_2, tuple_2, dict_2, y, eee, cabin]

print '\nMIXED_DATA_TYPES total count:', len(mixedDataTypes)

for item in mixedDataTypes:
    try:
        # if isinstance(item, ClassType): # use this for old class types (before 3.0)
        if isinstance(item, type):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isClass.append(mapping_as_str)
            isClass = [i for i in isClass if i != 'item']

        elif isinstance(item, ListType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isList.append(mapping_as_str)
            isList = [i for i in isList if i != 'item']

        elif isinstance(item, TupleType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isTuple.append(mapping_as_str)
            isTuple = [i for i in isTuple if i != 'item']

        elif isinstance(item, DictType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isDict.append(mapping_as_str)
            isDict = [i for i in isDict if i != 'item']

        elif isinstance(item, IntType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isInt.append(mapping_as_str)
            isInt = [i for i in isInt if i != 'item']

        elif isinstance(item, FloatType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isFloat.append(mapping_as_str)
            isFloat = [i for i in isFloat if i != 'item']

        elif isinstance(item, StringType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isString.append(mapping_as_str)
            isString = [i for i in isString if i != 'item']

        else:
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    other.append(mapping_as_str)
            other = [i for i in other if i != 'item']

    except (TypeError, AttributeError), e:
        print e

print '\n isClass:', len(isClass), isClass
print '  isList:', len(isList), isList
print ' isTuple:', len(isTuple), isTuple
print '  isDict:', len(isDict), isDict
print '   isInt:', len(isInt), isInt
print ' isFloat:', len(isFloat), isFloat
print 'isString:', len(isString), isString
print '   other:', len(other), other

# my output and the output I wanted
'''
MIXED_DATA_TYPES total count: 14

 isClass: 2 ['Class_1', 'Class_2']
  isList: 2 ['list_1', 'list_2']
 isTuple: 2 ['tuple_1', 'tuple_2']
  isDict: 2 ['dict_1', 'dict_2']
   isInt: 2 ['x', 'y']
 isFloat: 2 ['pie', 'eee']
isString: 2 ['house', 'cabin']
   other: 0 []
'''

내가 취할 문제는 이름이 객체의 속성이 아니라는 것입니다. 단일 객체에는 여러 이름이 있거나 이름이 전혀 없을 수 있습니다. 예를 들어 pi = pie코드에 추가 하면 isFloat목록에 추가 항목이 표시 됩니다. 당신이 추가 한 경우 tuple_1[0]귀하에 mixedDataTypes목록에는 이름 (문자열 덕분에 같은 객체를, 그들은 둘 수 있습니다 참조를 인턴하지만) 두 번 코드에있는 "한"에도 불구하고 그것을 발견되지 않습니다.
Blckknght

1
@Blckknght --- 동의합니다. 이것은 실제로 의도하지 않은 것을 수행하는 또 다른 방법입니다. 나는 그것이 독특한 결과를 낳거나 완벽하지 않다고 말하지 않았다. 이 작업에서 piand e변수 를 사용하면 원하지 않는 출력이 발생했으며 이는 둘 다 math라이브러리의 일부이기 때문 입니다. 나에게 이것은 최종 결과가 완벽하지 않더라도 수행 할 수 있는지 확인하는 운동 일뿐입니다. 이 언어를 배우면서 책을 통과하는 것은 지금까지만 진행되었습니다. 내 의견으로는, 당신이 정말로 언어를 배우고 싶다면 "만약"을하고 당신이 무엇을하는지보아야합니다.
Michael Swartz

1

easydict를 사용할 수 있습니다

>>> from easydict import EasyDict as edict
>>> d = edict({'foo':3, 'bar':{'x':1, 'y':2}})
>>> d.foo
3
>>> d.bar.x
1
>>> d = edict(foo=3)
>>> d.foo
3

다른 예시:

>>> d = EasyDict(log=False)
>>> d.debug = True
>>> d.items()
[('debug', True), ('log', False)]

1

python3 에서이 함수는 스택에서 가장 외부 이름을 얻습니다.

import inspect


def retrieve_name(var):
        """
        Gets the name of var. Does it from the out most frame inner-wards.
        :param var: variable to get name from.
        :return: string
        """
        for fi in reversed(inspect.stack()):
            names = [var_name for var_name, var_val in fi.frame.f_locals.items() if var_val is var]
            if len(names) > 0:
                return names[0]

코드의 어느 곳에서나 유용합니다. 첫 번째 일치 항목을 찾은 역 스택을 트래버스합니다.


0

이것은 끔찍한 아이디어 일지 모르지만 rlotun의 답변과 같은 줄에 있지만 정확한 결과를 더 자주 반환합니다.

import inspect
def getVarName(getvar):
  frame = inspect.currentframe()
  callerLocals = frame.f_back.f_locals
  for k, v in list(callerLocals.items()):
    if v is getvar():
      callerLocals.pop(k)
      try:
        getvar()
        callerLocals[k] = v
      except NameError:
        callerLocals[k] = v
        del frame
        return k
  del frame

당신은 이것을 다음과 같이 부릅니다.

bar = True
foo = False
bean = False
fooName = getVarName(lambda: foo)
print(fooName) # prints "foo"

0

목록을 가져와야합니다.

def get_var_name(**kwargs):
    """get variable name
        get_var_name(var = var)
    Returns:
        [str] -- var name
    """
    return list(kwargs.keys())[0]

0

변수 이름을 반환하지 않지만 전역 변수에서 쉽게 사전을 만들 수 있습니다.

class CustomDict(dict):
    def __add__(self, other):
        return CustomDict({**self, **other})

class GlobalBase(type):
    def __getattr__(cls, key):
        return CustomDict({key: globals()[key]})

    def __getitem__(cls, keys):
        return CustomDict({key: globals()[key] for key in keys})

class G(metaclass=GlobalBase):
    pass

x, y, z = 0, 1, 2

print('method 1:', G['x', 'y', 'z']) # Outcome: method 1: {'x': 0, 'y': 1, 'z': 2}
print('method 2:', G.x + G.y + G.z) # Outcome: method 2: {'x': 0, 'y': 1, 'z': 2}

0

함께 python-varname하면 쉽게 할 수 있습니다 :

pip install python-varname

from varname import Wrapper

foo = Wrapper(True)
bar = Wrapper(False)

your_dict = {val.name: val.value for val in (foo, bar)}

print(your_dict)

# {'foo': True, 'bar': False}

면책 조항 : 저는 해당 python-varname 라이브러리의 저자입니다.


-1
>>> a = 1
>>> b = 1
>>> id(a)
34120408
>>> id(b)
34120408
>>> a is b
True
>>> id(a) == id(b)
True

이 방법은 아마도 'a'또는 'b'에 대한 varname을 얻습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.