파이썬에서 객체의 속성을 열거하는 방법은 무엇입니까?


133

IC # 우리는 반사를 통해 그것을합니다. Javascript에서는 다음과 같이 간단합니다.

for(var propertyName in objectName)
    var currentPropertyValue = objectName[propertyName];

파이썬에서 어떻게합니까?



3
이 질문은 잘못된 것입니다. 대부분의 답변은 회원을 열거하는 입니다. 나는 속성 , 즉 장식 된 클래스의 멤버 를 열거하는 방법을 찾고 있었다 @property.
Tomasz Gandor

답변:


153
for property, value in vars(theObject).iteritems():
    print property, ": ", value

드문 경우지만 __slots__속성이 있으므로 이러한 클래스에는 종종 속성이 없습니다 __dict__.


1
이제 값을 변경하는 방법? Javascript에서는 다음을 수행 할 수 있습니다. object [property] = newValue. 파이썬에서 어떻게합니까?
Jader Dias

39
대신 setattr ()을 사용하십시오.
Nelson

1
@Nelson 왜 이것이 더 나은 선택인지 자세히 설명해 주시겠습니까? 더 짧거나 추가 고려 사항이 있습니까?
WhyNotHugo

8
@ Hugo : 먼저 "pythonic"이기 때문에, 그것은 대부분의 커뮤니티가 기대하는 구문입니다. 다른 구문은 코드를 읽는 모든 사람에게 불필요하게 일시 중지 될 수 있습니다. 둘째, 일부 유형은 setter를 구현합니다 __setattr__(). 사전에 직접 값을 설정하면 객체의 setter 및 / 또는 부모가 무시됩니다. 파이썬에서는 속성 설정 (예 : 위생) 중에 눈에 보이는 것보다 더 많은 일이 백그라운드에서 일어나고,이를 사용하여 setattr()놓치거나 직접 명시 적으로 처리하도록하는 것이 일반적입니다.
Michael Ekoka

3
@ Hi-Angel 그것은 효과 가있다 . 그러나 작동하지 않는 것은 파이썬에서 동적 상태 멤버 대 동적 상태를 갖는 선입견과 가정의 별자리입니다. 정적 멤버vars() 만 반환합니다 (예 : 객체 속성 및 해당 객체에 등록 된 메소드 ). 동적 멤버 (즉, 해당 오브젝트의 메소드 또는 유사한 마법에 의해 동적으로 정의 된 오브젝트 속성 및 메소드) 는 리턴 하지 않습니다 . 아마도 원하는 속성이 동적으로 정의 되어 또는에 사용할 수 없습니다 . __dict____getattr__()file.ImplementationNamevars()dir()
세실 카레

69

참조하십시오 inspect.getmembers(object[, predicate]).

이름별로 정렬 된 (이름, 값) 쌍 목록에서 객체의 모든 멤버를 반환합니다. 선택적 술어 인수가 제공되면 술어가 참 값을 리턴하는 멤버 만 포함됩니다.

>>> [name for name,thing in inspect.getmembers([])]
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', 
'__delslice__',    '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', 
'__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', 
'__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__','__reduce_ex__', 
'__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', 
'__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 
'insert', 'pop', 'remove', 'reverse', 'sort']
>>> 

예,이 답변은 훌륭합니다. 전에이 모듈을 사용한 적이 없습니다. getmembers ()는 dir (object), btw의 결과를 보냄으로써 구현됩니다.
Nelson

이것이 dict에 액세스하는 것보다 더 좋은 이유를 자세히 설명 할 수 있습니까 ? 파이썬 문서는 도움이되지 않습니다. 특히 일반적으로 attributes대신 용어 를 사용하기 때문에 members(둘 사이에 차이점이 있습니까?) 파이썬 3.0에서 이름을 수정하여 일관성을 유지할 수있었습니다.
nikow

죄송 __dict__합니다.
nikow

4
@nikow : inspect.getmembers ()는 내부 세부 정보가 변경 되어도 계속 작동합니다.
Georg Schölly

3
@NicholasKnight 는 동적 클래스 속성메타 클래스 속성을 포함 하고 (B) 전달 된 술어와 일치 하지 않는 멤버를 제외하고 (A) 의 (거의 무시할만한) 부수적 인 이점으로 inspect.getmembers()마무리 dir()합니다 . 하품 이요? 가능한 모든 객체 유형을 일반적으로 지원하는 타사 라이브러리에 적합합니다. 그러나 표준 사용 사례의 경우에는 충분합니다. inspect.getmembers()dir()
세실 카레

66

dir()간단한 방법입니다. 여기를 보아라:

파이썬 내부 검사 안내서


2
파이썬 문서에서 주목할 점은 dir ()은 주로 대화식 프롬프트에서 편리하게 사용할 수 있도록 제공되므로 엄격하거나 일관되게 정의 된 이름 세트를 제공하는 것보다 흥미로운 이름 세트를 제공하려고 시도하는 것입니다. 자세한 동작은 릴리스마다 다를 수 있습니다. 예를 들어, 인수가 클래스 인 경우 메타 클래스 속성이 결과 목록에 없습니다.
skyler

1
이 답변은 진료소에서 스크래치 작업을 수행 할 때 가장 좋습니다.

15 년 동안의 파이썬 (풀 타임 직업이 아님)과 나는 여전히 dir()감사합니다.
Abhishek Dujari

14

__dict__객체 의 속성은 정의 된 다른 모든 속성의 사전입니다. 파이썬 클래스는 getattr 을 무시 하고 속성처럼 보이지만 그렇지 않은 것을 만들 수 있습니다 __dict__. 또한 내장 기능이있다 vars()dir()미묘한 방법으로 다르다. 그리고 비정상적인 수업에서 __slots__대체 할 수 있습니다 __dict__.

파이썬에서는 객체가 복잡합니다. __dict__리플렉션 스타일 프로그래밍을 시작하기에 적합한 장소입니다. dir()대화식 쉘에서 해킹하는 경우 시작하는 곳입니다.


print vars.__doc__있음을 나타냅니다 With an argument, equivalent to object.__dict__그래서는 미묘한 차이가 뭘까요?
sancho.s ReinstateMonicaCellio


10

모든 속성을 반영하려면 위의 답변이 좋습니다.

단순히 사전의 키 (Python의 'object'와 다른 키)를 얻으려면 다음을 사용하십시오.

my_dict.keys()

my_dict = {'abc': {}, 'def': 12, 'ghi': 'string' }
my_dict.keys() 
> ['abc', 'def', 'ghi']

1
비록 그것이 내 대답이지만, 나는 그것이 받아 들여지는 대답이어야한다고 생각하지 않습니다 : 객체의 키는 클래스의 객체 인스턴스의 속성과 다릅니다. 그것들은 다르게 액세스되고 ( obj['key']vs. obj.property) 질문은 객체 속성에 관한 것이 었습니다. 나는 두 사람 사이에 혼란이 있기 때문에 대답을 여기에 넣었습니다.
MrE

실제로이 답변을 제거하는 것이 좋습니다.
Ente

위에서 언급했듯이 예를 들어 Javascript 또는 C #에서 온 사람들은 두 개념 사이에 차이가 없으므로 용어에 의해 쉽게 혼동됩니다. 파이썬을 배우고 키에 액세스하려고하는 사람들은 '속성'을 검색하고 여기에 결국 가능성이 있다고 생각합니다.
MrE December

그리고 당신은 옳지 만 요점을 그리워하십시오 : 다른 언어에서는 (JS를 가져 가십시오) 객체와 사전 사이에는 구별이 없습니다. OP는 C #에서 질문합니다. 이 답변은 잘못되었지만 11 개의 공감대를 얻었습니다. 여기에 착륙 한 사람들이 엄격한 파이썬 링고에서 질문을 볼 때 기술적으로 정답이 아니라고하더라도 유용하다는 것을 증명합니다. 더 선명하게 편집 할 것입니다.
MrE

5

이것은 다른 답변으로 완전히 다루어 지지만 명시 적으로 설명하겠습니다. 객체에는 클래스 속성과 정적 및 동적 인스턴스 속성이있을 수 있습니다.

class foo:
    classy = 1
    @property
    def dyno(self):
        return 1
    def __init__(self):
        self.stasis = 2

    def fx(self):
        return 3

stasis정적 dyno이며 동적이며 (속성 데코레이터 참조) classy클래스 속성입니다. 우리가 단순히 그렇게 __dict__하거나 vars정적 인 것만 얻는다면.

o = foo()
print(o.__dict__) #{'stasis': 2}
print(vars(o)) #{'stasis': 2}

우리가 원한다면 다른 사람들 __dict__이 모든 것을 얻을 것입니다. 여기에는 매직 메소드와 속성 및 노멀 바운드 메소드가 포함됩니다. 따라서 피하십시오 :

d = {k: getattr(o, k, '') for k in o.__dir__() if k[:2] != '__' and type(getattr(o, k, '')).__name__ != 'method'}
print(d) #{'stasis': 2, 'classy': 1, 'dyno': 1}

type속성 장식 방법 (동적 속성)로 호출, 당신에게 반환 된 값의 유형을하지 줄 것이다 method. 이것을 증명하기 위해 json을 문자열 화하십시오.

import json
print(json.dumps(d)) #{"stasis": 2, "classy": 1, "dyno": 1}

그것이 추락했을 방법이었습니다.

TL; DR. extravar = lambda o: {k: getattr(o, k, '') for k in o.__dir__() if k[:2] != '__' and type(getattr(o, k, '')).__name__ != 'method'}세 가지 방법 모두를 시도 하지만 방법이나 마술은 아닙니다.

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