2014-07-26 3 views
5

대 요즘 일부 tweets 및으로 hasattr에 대한 python documentation을 읽고 그리고 그것은 말한다 :파이썬으로 hasattr getattr

으로 hasattr (객체 명)

인수는 객체와 문자열입니다. 문자열이 객체의 속성 중 하나 인 경우 결과는 True이고 그렇지 않으면 False입니다. 은 (이것은 getattr (개체, 이름)을 호출하고 그것이 AttributeError를 제기 여부보고에 의해 구현됩니다.) 그 용서를 물어 쉽게이 말한다 파이썬에서 모토가있다

내가 보통 동의하는 허가보다. 결과에

import timeit 
definition="""\ 
class A(object): 
    a = 1 
a = A() 
""" 

stm="""\ 
hasattr(a, 'a') 
""" 
print timeit.timeit(stmt=stm, setup=definition, number=10000000) 

stm="""\ 
getattr(a, 'a') 
""" 
print timeit.timeit(stmt=stm, setup=definition, number=10000000) 

:

$ python test.py 
hasattr(a, 'a') 
1.26515984535 

getattr(a, 'a') 
1.32518696785 

I've가 무슨 일 경우 속성 아무튼 또한 시도

나는 정말 간단한 파이썬 코드로이 경우에는 성능 테스트를하려고 존재하지 않으며 getattr과 hasattr 사이의 차이가 더 큽니다. 그래서 지금까지 내가 본 것은 getattr이 hasattr보다 느리다는 것입니다.하지만 getattr을 호출하는 문서에서 말합니다.

는 I've는 hasattrgetattr의 CPython의 구현을 검색하고는 모두 다음 함수를 호출 할 것 같다 :

v = PyObject_GetAttr(v, name); 

을하지만, 아마 느리게 만드는으로 hasattr보다 getattr 더 상용구가 있습니다.

누구나 문서에서 우리는 hasattr이 getattr을 호출한다고 말하고 있습니다. 실제로 성능 때문에 isattr 대신 getattr을 사용하도록 권장하는 것 같습니다. 그것은 단지 더 파이톤이기 때문입니까? 어쩌면 나는 내 테스트 :

감사에서 뭔가 잘못하고있는 중이 야

,

라울

+3

여기의 차이 성능이 아닙니다. 당신은 5 나노초 정도를 말하는 겁니다. 파이썬 만 사용하면 수천 번을 잃어 버릴 수 있습니다. 차이점은 여기에 필요한 것이 맞는지 여부입니다. – cHao

+0

성능 차이가 그다지 중요하지 않았습니다. 나는 그것이 getattr을 호출하는 것으로 구현되었다는 것을 설명하는 문서의 주석이 왜 있었는지 이해하지 못했습니다. – raulcumplido

+0

어쩌면 한 번에'getattr'을 호출했는데 지금은 그렇지 않지만 아무도 문서를 업데이트하지 않았습니다 ...? 솔직히, 그것은 어쨌든 API 문서에 속하지 않는 종류의 성명서입니다. 문서는 "어떻게"가 "무엇"의 필수적인 부분이 아닌 한, 일어나는 일이 아니라 어떻게되는지를 설명해야합니다. – cHao

답변

10

문서는 권장하지 않습니다이 문서는 명백한을 말한다. hasattr은 그 자체로 구현되며, 속성 게터에서 AttributeError을 던지면 속성이 존재하지 않는 것처럼 보일 수 있습니다. 이는 중요한 세부 사항이므로 문서에 명시 적으로 언급 된 이유입니다. 예를 들어,이 코드를 고려하십시오

class Spam(object): 
    sausages = False 

    @property 
    def eggs(self): 
     if self.sausages: 
      return 42 
     raise AttributeError("No eggs without sausages") 

    @property 
    def invalid(self): 
     return self.foobar 


spam = Spam() 
print(hasattr(Spam, 'eggs')) 

print(hasattr(spam, 'eggs')) 

spam.sausages = True 
print(hasattr(spam, 'eggs')) 

print(hasattr(spam, 'invalid')) 

결과가를 Spam 클래스 eggs에 대한 속성 설명을 가지고 있지만

True 
False 
True 
False 

게터는 그 클래스의 AttributeErrornot self.sausages 경우, 인스턴스를 제기하기 때문에 "hasattr"eggs이 아닙니다.

이외의 경우 에는이 필요하지 않은 경우에만 hasattr을 사용하십시오. 값이 필요한 경우 getattr에 2 개의 인수를 사용하고 예외를 catch하거나 3 개의 인수를 사용합니다. 세 번째 인수는 적절한 기본값입니다.

getattr을 (사용 결과) (2.7.9) :

>>> spam = Spam() 
>>> print(getattr(Spam, 'eggs')) 
<property object at 0x01E2A570> 
>>> print(getattr(spam, 'eggs')) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 7, in eggs 
AttributeError: No eggs without sausages 
>>> spam.sausages = True 
>>> print(getattr(spam, 'eggs')) 
42 
>>> print(getattr(spam, 'invalid')) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 10, in invalid 
AttributeError: 'Spam' object has no attribute 'foobar' 
>>> 
1

hasattr 예외 (적어도 in Python 2.7)를 삼키는에 문제가있다, 그래서 아마 고정 될 때까지로부터 거리를 더 나은 것 같다 . 예를 들어

테이크, the following code는 :

>>> class Foo(object): 
...  @property 
...  def my_attr(self): 
...   raise ValueError('nope, nope, nope') 
... 
>>> bar = Foo() 
>>> bar.my_attr 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 4, in my_attr 
ValueError: nope, nope, nope 
>>> hasattr(Foo, 'my_attr') 
True 
>>> hasattr(bar, 'my_attr') 
False 
>>> getattr(bar, 'my_attr', None) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 4, in my_attr 
ValueError: nope, nope, nope 
>>> 
관련 문제