파이썬에서 객체에 속성이 있는지 확인하는 방법


1635

파이썬에서 객체에 속성이 있는지 확인하는 방법이 있습니까? 예를 들면 다음과 같습니다.

>>> a = SomeClass()
>>> a.someProperty = value
>>> a.property
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: SomeClass instance has no attribute 'property'

a속성 property을 사용하기 전에 속성 이 있는지 어떻게 알 수 있습니까?

답변:


2337

시도 hasattr():

if hasattr(a, 'property'):
    a.property

편집 : 용서 요청에 대한 좋은 조언을 제공하는 아래 zweiterlinde의 답변을 참조하십시오 ! 매우 파이썬적인 접근 방식!

파이썬의 일반적인 관행은 속성이 대부분의 시간에있을 가능성이 높으면 단순히 호출하여 예외가 전파되도록하거나 try / except 블록으로 트랩하는 것입니다. 보다 빠를 것 hasattr입니다. 속성이 대부분 없을 것 같거나 확실하지 않은 hasattr경우 반복적으로 예외 블록에 빠지는 것보다 사용 속도가 더 빠릅니다.


19
네임 스페이스에서 함수를 검사하기 위해 작동하는 것 같습니다. 예 : import string hasattr(string, "lower")
riviera

15
hasattrtry/ 를 사용하는 것과 정확히 동일합니다 except AttributeError. (파이썬 2.7에서) hasattr의 docstring은 getattr 손을 사용하여 예외를 포착한다고 말합니다.
Jeff Tratner

8
@JeffTratner : hasattr불행히도 모든 예외잡을 수 있으므로 Python 2.x 와 정확히 동일 하지 않습니다 . 예제와 간단한 해결 방법 은 내 답변 을 참조하십시오 . try: ... except AttributeError:hasattr
Martin Geisler

1
@MartinGeisler 좋은 지적-그것은 모든 예외를 잡는 것과 같지 않습니다. 어떤 버전이 더 정확한지 확실하지 않습니다. 실제로 작업하는 가정과 함수를 호출하는 사람에 따라 다릅니다. 설명해 주셔서 감사합니다.
Jeff Tratner

2
hasattr예를 들면 다음과 같습니다.[a.property for a in list_of_as if hasattr(a, "property")]
Rafael Martins

631

Jarret Hardie 가 대답 했듯이 hasattr트릭을 수행 할 것입니다. 그러나 파이썬 커뮤니티의 많은 사람들이 "도약하기 전에"(LBYL)보다는 "권한보다 용서를 구하는 것이 더 쉽다"(EAFP) 전략을 추천하고 싶다고 덧붙이고 싶습니다. 다음 참조를보십시오 :

EAFP vs LBYL (Re : 지금까지 조금 실망했습니다)
EAFP vs. LBYL @Code Pythonista와 같은 : 관용적 파이썬

즉 :

try:
    doStuff(a.property)
except AttributeError:
    otherStuff()

...가 선호됩니다 :

if hasattr(a, 'property'):
    doStuff(a.property)
else:
    otherStuff()

257
그러나 doStuff ()가 아닌 AttributeError를 일으킨 a.property인지 어떻게 확인합니까? 당신이하지 않는 것 같습니다. 용서를 구하는 것이 정말 쉽지만 여러 번 잘못되었습니다.
jpalecek 2009

282
EAFP는 ... 미친 것 같습니다. HasAttr은 특정 속성을 확인하고있는 미래의 유지 보수 프로그래머에게 전보합니다. 예외를 얻는 것은 미래의 프로그래머에게 아무 것도 알려주지 않으며 누군가 토끼 구멍을 내릴 수 있습니다.
Ethan Heilman

74
@ e5 :이 경우 공정한 점이 있지만 많은 경우 EAFP가 유일한 올바른 옵션입니다. 예를 들어, 파일이 있는지 확인한 다음 파일을 열면 파일이 확실히 존재할 것으로 예상되므로 코드가 올바르지 않습니다. 파일이 확인과 사용 사이에 삭제되거나 이름이 변경 될 수 있습니다. 이를 TOCTOU 오류 (Time-Of-Check-To-Time-Of-Use)라고하며 충돌을 일으키는 것 외에도 보안 취약점의 원인이 될 수 있습니다.
Max

15
@EthanHeilman 예외의 원인이 모호 할 때만 미쳤으며, 대부분의 경우 좋은 디자인으로 피할 수 있습니다. try / except / 내의 논리를 잘 계층화하면 일반적으로 각 소비 코드에 대해 선 입적 ​​if-checks로 코드를 흩 뜨리는 것보다 더 강력한 (프로그래머 오류가 발생하기 쉬운) 논리를 만듭니다. 오류를 매우 명확하게하고, 프로그래머가 직접 오류를 처리 할 수있는 옵션을 제공합니다.
피터 M. 엘리아스

64
여기서 모호한 불만의 대부분은 단순히 샘플 코드의 구조가 잘못 되었기 때문입니다. 내부의 유일한 것은 try:시도 된 속성 액세스 여야합니다. 실행을 마무리 할 이유가 없습니다 doStuff. 그래도 모호한 가능성이 여전히 있습니다 property. 일반 속성 대신 계산 된 속성 인 경우 구현이 AttributeError내부적으로 증가 할 수 있습니다. 이것이 거의 모든 실제 상황에서 또는 잡기 getattr보다 선호되는 이유입니다 . hasattrAttributeError
Carl Meyer

484

사용 hasattr()하거나 catch 할 수 AttributeError있지만 속성 값이없는 경우 기본값을 사용하여 속성 값을 원한다면 가장 좋은 옵션은 getattr()다음과 같습니다.

getattr(a, 'property', 'default value')

14
a) 가능한 AttributeError 소스의 모호성, b) EAFP 접근 방식 유지.
피터 M. 엘리아스

6
또한 코드 라인의 25 %입니다. 확실히 이것이 최상의 솔루션이어야합니다.
fatuhoku

16
"실제로 속성 값을 기본값으로 사용하려는 경우"가 가장 좋습니다. 이것이 많은 사람들이 속성이 존재하는지 여부를 감지하려고 할 때 실제로 원하는 것이라고 생각하지만 OP는 실제로 속성을 요구하므로 해당 질문에 대한 직접 답변 (hasattr, AttributeError)이 더 높게 나열되는 것이 합리적입니다. .
Carl Meyer 5

41

나는 당신이 찾고있는 것이 hasattr 이라고 생각합니다 . 당신이 감지하려는 경우,이 같은 것을 권하고 싶습니다 파이썬 속성 -

try:
    getattr(someObject, 'someProperty')         
except AttributeError:
    print "Doesn't exist"
else
    print "Exists"

여기서 단점은 속성 __get__코드의 속성 오류 도 발견 된다는 것입니다 .

그렇지 않으면

if hasattr(someObject, 'someProp'):
    #Access someProp/ set someProp
    pass

문서 : http://docs.python.org/library/functions.html
경고 :
내 추천 이유는 hasattr이 속성을 감지하지 못하기 때문입니다.
링크 : http://mail.python.org/pipermail/python-dev/2005-December/058498.html


그래서, 당신의 조언은 당신이 구축하지 않습니다-그것을 구현하십시오!
SilentGhost

정확하지는 않지만 속성을 감지하려는 내장 IFF를 사용하지 마십시오. 그렇지 않으면 hasattr이 완벽하게 좋습니다.
batbrat

3
hasattr일반적으로 속성을 잘 감지합니다. 단지 property-wrapped 함수 에서 예외 발생을 처리하는 것은 그러한 속성이 존재하지 않는다는 것을 의미합니다. 연결된 Python 메일 링리스트 게시물은 액세스하려고 할 때 예외를 발생시키는 속성에 관한 것입니다. 모든 실질적인 목적으로, 상기 속성은 값을 생성하지 않기 때문에 존재하지 않습니다. 또한 hasattrPy 3.1 이하에서는 일반적으로 예외 만 억제합니다. 3.2 이상에서는 (replaceing with Falsereturn) 만 억제 AttributeError합니다.
ShadowRanger

32

pydoc에 따르면 hasattr (obj, prop)은 getattr (obj, prop)를 호출하고 예외를 포착합니다. 따라서 try 문으로 속성 액세스를 래핑하고 사전에 hasattr ()을 사용하는 것과 같이 AttributeError를 잡는 것도 유효합니다.

a = SomeClass()
try:
    return a.fake_prop
except AttributeError:
    return default_value

2
잘 hasattr은 실제로 최적화 될 수 있습니다 . 예를 들어 pypy.
odinho-Velmont

6
+1. 이것은 재정의 할 때 사용하는 것보다 훨씬 안전합니다. 왜냐하면 파이썬 2.x의 모든 예외를 예상했던 것처럼 잡을 수 있기 때문 입니다 . 이것은 Python 3.2에서 수정되었습니다 . 간단한 해결 방법은 다른 답변 을 참조하십시오 . hasattrSomeClass__getattr__hasattrAttributeError
Martin Geisler

24

나는 이것을 피할 것을 제안하고 싶다 :

try:
    doStuff(a.property)
except AttributeError:
    otherStuff()

@jpalecek 사용자가 그것을 언급했습니다 : AttributeError내부 doStuff()에서 발생 하면 손실됩니다.

어쩌면이 접근법이 더 낫습니다.

try:
    val = a.property
except AttributeError:
    otherStuff()
else:
    doStuff(val)

또한 단지 수 : try: a.property좌측 사이드에 대한 필요가 없습니다
Petruza

그런 다음 else 블록에서 a.property를 반복해야하며 실패 할 수 있습니다.
Éric Araujo

13

상황에 따라 isinstance어떤 종류의 객체를 가지고 있는지 확인한 다음 해당 속성을 사용할 수 있습니다. Python 2.6 / 3.0 에 추상 기본 클래스 가 도입 되면서이 접근 방식도 훨씬 강력 해졌습니다 (기본적으로 ABC는보다 정교한 오리 입력 방식을 허용합니다).

한 가지 상황은 두 개의 서로 다른 객체가 동일한 이름을 가지고 있지만 의미가 다른 속성을 갖는 경우 유용합니다. hasattr그런 다음에 만 사용하면 이상한 오류가 발생할 수 있습니다.

좋은 예 중 하나는 이터레이터와 이터 러블 사이의 구별입니다 ( 질문 참조 ). __iter__이터레이터와 이터 러블 의 메소드는 이름은 같지만 의미 상 상당히 다릅니다! 따라서 hasattr쓸모는 없지만 isinstanceABC와 함께 깨끗한 솔루션을 제공합니다.

그러나 대부분의 상황에서 hasattr(다른 답변에 설명 된) 접근 방식이 가장 적합한 솔루션 이라는 데 동의합니다 .


13

hasattr ()을 기대하고 있지만 hasattr ()을 피하고 getattr ()을 선호하십시오. getattr ()은 hasattr ()보다 빠릅니다.

hasattr () 사용 :

 if hasattr(a, 'property'):
     print a.property

여기에 동일한 속성이 없으면 getattr을 사용하여 속성을 가져옵니다.

   property = getattr(a,"property",None)
    if property:
        print property

11

편집 :이 접근 방식에는 심각한 제한이 있습니다. 객체가 반복 가능한 객체라면 작동해야합니다 . 아래의 의견을 확인하십시오.

Python 3.6 이상을 사용 하는 경우 객체에 특정 속성이 있는지 확인하는 편리한 대안이 있습니다.

if 'attr1' in obj1:
    print("attr1 = {}".format(obj1["attr1"]))

그러나 현재 어느 것이 가장 좋은 방법인지 잘 모르겠습니다. 사용 hasattr(), 사용 getattr()또는 사용 in. 의견을 환영합니다.


6
in키워드는 반복 가능한 유형을 확인하는 데 사용됩니다. 예를 들어, 'foo' in None오류가 발생 TypeError: argument of type 'NoneType' is not iterable합니다. 수정은 사용하기 전에 유형이 반복 가능한지 확인하는 것 in입니다. 반복 불가능한 유형과 같은 엣지 케이스를 수정 한 후에는 엣지 케이스 hasattr()를 처리하도록 설계되었으므로 사용하는 것이 좋습니다 .
Seth Difley

3
이것은 속성 액세스와 관련이 없습니다. 나는 그것이 어떻게 upvoted되었는지 전혀 모른다. dict자바 스크립트 객체의 디자인과 유사한 "경량 객체"로 사용 하는 경우 액세스를 속성으로 지정해야하는 유일한 유사점 이지만 대부분의 일반 클래스는이를 일반적으로 지원하지 않습니다 (@SethDifley에서 언급 한 오류에 대한 변형을 얻음) .
ShadowRanger

2
class .__ dict__에서 'variable'인 경우 : ??
Ben

6

매우 직관적 인 접근 방식은 다음과 같습니다.

if 'property' in dir(a):
    a.property

1

이것은 매우 간단합니다. 단지 dir(객체를 사용하십시오. )
이것은 객체의 사용 가능한 모든 함수와 속성의 목록을 반환합니다.


1

또 다른 가능한 옵션이지만 이전에 의미하는 바에 따라 다릅니다 .

undefined = object()

class Widget:

    def __init__(self):
        self.bar = 1

    def zoom(self):
        print("zoom!")

a = Widget()

bar = getattr(a, "bar", undefined)
if bar is not undefined:
    print("bar:%s" % (bar))

foo = getattr(a, "foo", undefined)
if foo is not undefined:
    print("foo:%s" % (foo))

zoom = getattr(a, "zoom", undefined)
if zoom is not undefined:
    zoom()

산출:

bar:1
zoom!

이를 통해 값이없는 속성을 확인할 수도 있습니다.

그러나! 이 경우에는 작동하지 undefined않으므로 여러 위치를 실수로 인스턴스화하고 비교하지 않도록 매우주의하십시오 is.

최신 정보:

위의 단락에서 경고 한 내용으로, 일치하지 않는 여러 정의되지 않은 항목이 있으므로 최근 에이 패턴을 약간 수정했습니다.

undefined = NotImplemented

NotImplemented와 혼동하지 말고 NotImplementedError내장되어 있습니다. JS의 의도와 반 일치하고 undefined어디서나 정의를 재사용 할 수 있으며 항상 일치합니다. 단점은 부울에서 "트러스트"이고 로그 및 스택 추적에서 이상하게 보일 수 있다는 것입니다 (그러나이 컨텍스트에서만 나타남을 알면 빠르게 극복합니다).


0

내장 메소드 object를 사용하여 속성이 포함되어 있는지 확인할 수 있습니다 hasattr.

객체가 a있고 속성을 확인하려는 경우 인스턴스의 경우stuff

>>> class a:
...     stuff = "something"
... 
>>> hasattr(a,'stuff')
True
>>> hasattr(a,'other_stuff')
False

메소드 서명 자체 인 hasattr(object, name) -> bool경우, 이는 평균 object보유 특성 의 두 번째 인수로 전달되는 hasattr것이보다 부울 제공 True또는 False존재에 따른 name오브젝트 속성.


0

hasattr()정답입니다. 내가 추가하고 싶은 것은 asserthasattr() 와 함께 잘 사용할 수 있다는 것입니다 (불필요한 진술 을 피하고 코드를 더 읽기 쉽게 만듭니다).if

assert hasattr(a, 'property'), 'object lacks property' 

SO에 대한 다른 답변에서 언급 한 바와 같이, Assert는 절대 발생하지 않아야하는 조건을 테스트하는 데 사용해야합니다. 프로그램 상태가 손상된 경우 일찍 충돌하는 것이 목적입니다.


이것은 도움이되지만 항상 그런 것은 아닙니다. 아마도 객체에 속성이 있는지 테스트 한 다음 처음으로 추가하거나 해당 속성을 가진 객체에 대해 다른 코드를 실행해야 할 수도 있습니다. 코드를 계속할 수 없으면 어설 션이 정상일 수 있습니다. 그러나 다시, 항상 그런 것은 아닙니다. 중요한 것은 hasattr주변 코드를 사용 하지 않는 것입니다 .
루카스 가브리엘 산체스
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.