2014-07-26 28 views
5

vs Son zamanlarda bazı tweets ve hasattr hakkında python documentation okuma edilmiş ve şöyle der:Python hasattr getattr

hasattr (nesne, isim)

argümanları bir nesne ve bir dize vardır. Dize, nesnenin özniteliklerinden biri olan > adı ise, yanlış değilse, sonuç doğrudur. (Bu getattr (nesne, isim) çağırarak ve bir AttributeError yükseltir olmadığını görerek uygulanmaktadır.) O af dilemesini kolay olduğunu söylüyor Python bir sloganı vardır

genellikle kabul ettiğim izninden daha fazla. sonuçlarla

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 

boyunca hep şeffaf ne olur nitelik doesn da denedik

Bunu çok basit piton kodunu bu durumda bir performans testini yapmaya çalıştık Yoktur ve getattr ile hasattr arasındaki farklar daha büyüktür. Öyleyse şimdiye kadar gördüğüm şey, getattr'ın hasattr'den daha yavaş olmasıdır, fakat belgelerde getattr diyor.

boyunca hep şeffaf hasattr ve getattr ait CPython uygulanmasını arandı ve her iki yanındaki işlevini çağırmak gibi görünüyor:

v = PyObject_GetAttr(v, name); 

ama muhtemelen daha yavaş yapar hasattr daha getattr fazla klişe vardır.

Neden belgelemede gratttr gratttr dediğimizi ve neden performansa bağlı olmadığına dair kullanıcılara gtrttr kullanmasını teşvik ettiğimizi kimse biliyor mu? Sadece daha pythonic olduğu için mi? Belki de testi :)

sayesinde yanlış bir şey yapıyorum

,

Raúl

+3

burada fark performans değil. 5 nanosaniye gibi konuşuyorsun. Python'u kullanarak binlerce kez kaybedersiniz. Buradaki fark, yapmanız gereken şey için doğru olanıdır. – cHao

+0

Performans farkı nokta değildi. Neden getattr çağrıldığını bildiren belgelerindeki yorum neden orada olduğunu anlamadım. – raulcumplido

+0

Belki bir noktada 'getattr 'diye adlandırdı, şimdi değil, ama hiç kimse dokümanlar ... Açıkçası, yine de, bu yine de API belgelerine ait olmayan bir ifadedir. “Nasıl” nın “ne” nin önemli bir parçası olmadığı sürece, dokümanlar neler olduğunu açıklamalıdır. – cHao

cevap

10

dokümantasyon teşvik etmez, dokümantasyon sadece belirgin belirtiyor. hasattr, bu şekilde uygulanır ve bir özellik toplayıcısından AttributeError atmak, öznitelik var gibi görünmesini sağlayabilir. Bu önemli bir ayrıntıdır ve bu nedenle belgelerde açıkça belirtilmiştir. Örneğin bu kodu düşünün:

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

sonucudur Spam sınıf eggs için bir özellik tanımlayıcısı vardır, ancak

True 
False 
True 
False 

alıcı bu sınıfın AttributeErrornot self.sausages, o zaman örneğini yükseltir beri "hasattr" eggs.

Bunun dışında, yalnızca değerine gerek duymazsanız, hasattr'u kullanın; Değere ihtiyacınız varsa, 2 argümanlı getattr kullanın ve istisnayı veya 3 argümanı yakalayın, üçüncüsü ise mantıklı bir varsayılan değerdir.

getattr (kullanarak sonuçları) (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 istisnalar (en azından in Python 2.7) yutma ile ilgili bir sorun vardır, bu yüzden muhtemelen sabit olana kadar ondan uzak durmasını iyi olduğu görünüyor . Örneğin

alın, the following code: