2016-02-23 17 views
5

Neden hasattr örneğinde, örneğin foo özniteliği yok mu? Python's hasattr bazen yanlış bir sonuç döndürüyor

>>> class A(object): 
...  @property 
...  def foo(self): 
...   ErrorErrorError 
... 
>>> a = A() 
>>> hasattr(a, 'foo') 
False 

beklediğim:

>>> hasattr(a, 'foo') 
NameError: name 'ErrorErrorError' is not defined` 

cevap

11

hasattr ait python2 uygulaması oldukça naif olduğunu, sadece o niteliği erişebilir ve bunun bir istisna yükseltir olup olmadığını görmek için çalışır.

Maalesef, bu, mülk içindeki işlenmemiş istisnaların yutulacağı ve bu koddaki hataların kaybolabileceği anlamına gelir. Hasarlara hakaret eklemek için, hasattr istisna yediğinde, aynı zamanda yanlış bir cevap da verecektir (burada var ise, sonuç True sonucuna geri dönmüş olmalıdır). python3.2 + içinde

, davranış düzeltilmiştir:

hasattr(object, name)

argümanları bir amacı bir dizi bulunmaktadır. Dize, nesnenin özniteliklerinden birinin adıysa ise, False ise.

düzeltme here olduğunu (Bu. getattr(object, name) arayarak ve bir AttributeError veya olmasın yükseltir olmadığını görerek uygulanan), ama ne yazık ki değişiklik backport etmedi.

Python2 davranışı sizin için sorun yaratırsa, hasattr; bunun yerine, getattr etrafında bir deneyin/hariç özelliğini kullanabilirsiniz, yalnızca AttributeError istisnasını yakalayabilir ve başkalarının işlenmeden kaldırılmasına izin verebilirsiniz.

+4

Python belgelerinden alınan alıntılar, "hasattr" davranışına rağmen hala tuhaf sayılabilir. Bir mülkün içindeki keyfi istisnaların artık özniteliğin yokluğuna (daha doğrusu arayanın yüzüne doğru yükseltilmiş olmasına) neden olmadığı doğrudur, ancak bir "AttributeError" özelliği mülkün herhangi bir yerinden kaynaklanıyorsa, "hasattr" sonucunu yine de Yanlış ol. Bu kasıtlı olmayabilir. (Ya da, öyle ki, bir özellik "orada" olmak isteyip istemediğini kendi başına belirleyebilir.) Her halükarda, mülkün yürütülmesi, yan etkiler göz önünde bulundurulduğunda, ilk etapta yanlıştır. –

+0

Gerçekten basit bir yol yoktur. "AttributeError" öğesinin öznitelik alma makinesinin kendisi tarafından mı, yoksa bir özellikte kodla mı yükseltildiğini belirlemek için. – kindall

İlgili konular