Pertanyaan Hasattr Python kadang-kadang mengembalikan hasil yang salah


Kenapa hasattr mengatakan bahwa instance tersebut tidak memiliki foo atribut?

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

Saya mengharapkan:

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

5
2018-02-23 00:37


asal


Jawaban:


Implementasi python2 dari hasattr cukup naif, hanya mencoba untuk mengakses atribut itu dan melihat apakah itu menimbulkan pengecualian atau tidak.

Sayangnya, ini berarti bahwa setiap pengecualian yang tidak tertangani di dalam properti akan tertelan, dan kesalahan dalam kode itu bisa hilang. Untuk menambahkan penghinaan ke luka, ketika hasattr makan pengecualian, itu juga akan mengembalikan jawaban yang salah (di sini atribut a.foo  tidak ada, jadi hasilnya pasti sudah kembali True jika ada).

Dalam python3.2 +, perilaku telah diperbaiki:

hasattr(object, name)

Argumennya adalah objek dan string. Hasilnya adalah True jika string adalah nama salah satu atribut objek, False jika tidak. (Ini diimplementasikan dengan menelepon getattr(object, name) dan melihat apakah itu menimbulkan AttributeError atau tidak.)

Perbaikannya adalah sini, tapi sayangnya perubahan itu tidak mendukung.

Jika perilaku python2 menyebabkan masalah bagi Anda, pertimbangkan untuk tidak menggunakannya hasattr; sebagai gantinya Anda dapat menggunakan try / kecuali sekitar getattr, hanya menangkap AttributeError perkecualian dan membiarkan orang lain mengangkat tidak tertangani.


12
2018-02-23 00:37