Apakah ada cara di Python untuk menentukan apakah suatu objek memiliki beberapa atribut? Sebagai contoh:
>>> 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'
Bagaimana Anda tahu apakah a
memiliki atribut property
sebelum menggunakannya?
sumber
import string hasattr(string, "lower")
hasattr
persis sama dengan menggunakantry
/except AttributeError
: docstring dari hasattr (dalam Python 2.7) mengatakan bahwa ia menggunakan getattr tangkapan tangan pengecualian.hasattr
sayangnya tidak persis sama dengantry: ... except AttributeError:
di Python 2.x karenahasattr
akan menangkap semua pengecualian . Silakan lihat jawaban saya untuk contoh dan solusi sederhana.Seperti Jarret Hardie menjawab,
hasattr
akan melakukan trik. Saya ingin menambahkan, bahwa banyak di komunitas Python merekomendasikan strategi "lebih mudah untuk meminta pengampunan daripada izin" (EAFP) daripada "lihat sebelum Anda melompat" (LBYL). Lihat referensi ini:EAFP vs LBYL (adalah Re: Sedikit kecewa sejauh ini)
EAFP vs LBYL @Code Like a Pythonista: Idiomatic Python
yaitu:
... lebih disukai daripada:
sumber
try:
seharusnya adalah akses atribut yang dicoba; tidak ada alasan untuk membungkus eksekusidoStuff
juga. Namun, masih ada beberapa potensi ambiguitas: jikaproperty
merupakan properti yang dihitung alih-alih atribut biasa, implementasinya dapat meningkat secaraAttributeError
internal. Inilah sebabnya mengapa dalam hampir semua situasi nyata seperti ini,getattr
lebih disukai daripadahasattr
menangkap atau menangkapAttributeError
.Anda dapat menggunakan
hasattr()
atau menangkapAttributeError
, tetapi jika Anda benar-benar hanya ingin nilai atribut dengan default jika tidak ada, opsi terbaik adalah dengan menggunakangetattr()
:sumber
Saya pikir apa yang Anda cari adalah hasattr . Namun, saya akan merekomendasikan sesuatu seperti ini jika Anda ingin mendeteksi properti python -
Kerugian di sini adalah bahwa kesalahan atribut dalam
__get__
kode properti juga ditangkap.Kalau tidak, jangan-
Documents: http://docs.python.org/library/functions.html
Peringatan:
Alasan rekomendasi saya adalah bahwa hasattr tidak mendeteksi properti.
Tautan: http://mail.python.org/pipermail/python-dev/2005-December/058498.html
sumber
hasattr
mendeteksi properti secara umum baik-baik saja. Hanya saja itu memperlakukan meningkatkan pengecualian dalamproperty
fungsi -wrapped karena berarti tidak ada atribut seperti itu; posting milis Python yang ditautkan adalah tentang properti yang menimbulkan pengecualian ketika Anda mencoba mengaksesnya. Untuk semua tujuan praktis, atribut tersebut tidak ada, karena tidak akan pernah menghasilkan nilai. Juga,hasattr
hanya menekan pengecualian secara umum pada Py 3.1 dan sebelumnya; di 3.2+, itu hanya menekan (mengganti denganFalse
kembali)AttributeError
.Menurut pydoc, hasattr (obj, prop) cukup memanggil getattr (obj, prop) dan menangkap pengecualian. Jadi, sama validnya untuk membungkus akses atribut dengan pernyataan coba dan tangkap AttributeError karena menggunakan hasattr () sebelumnya.
sumber
hasattr
ketikaSomeClass
ditimpa__getattr__
karenahasattr
akan menangkap semua pengecualian dalam Python 2.x, tidakAttributeError
seperti yang Anda harapkan. Ini diperbaiki dalam Python 3.2 - silakan lihat jawaban saya yang lain untuk solusi sederhana.Saya ingin menyarankan untuk menghindari ini:
Pengguna @jpalecek menyebutkannya: Jika
AttributeError
terjadi di dalamdoStuff()
, Anda hilang.Mungkin pendekatan ini lebih baik:
sumber
Tergantung pada situasi Anda dapat memeriksa dengan objek
isinstance
apa yang Anda miliki, dan kemudian menggunakan atribut yang sesuai. Dengan diperkenalkannya kelas dasar abstrak di Python 2.6 / 3.0 pendekatan ini juga menjadi jauh lebih kuat (pada dasarnya ABC memungkinkan cara yang lebih canggih untuk mengetik bebek).Satu situasi adalah ini berguna jika dua objek yang berbeda memiliki atribut dengan nama yang sama, tetapi dengan makna yang berbeda. Hanya menggunakan
hasattr
bisa menyebabkan kesalahan aneh.Satu contoh yang bagus adalah perbedaan antara iterator dan iterables (lihat pertanyaan ini ). The
__iter__
metode dalam iterator dan iterable memiliki nama yang sama tetapi secara semantik sangat berbeda! Jadihasattr
tidak ada gunanya, tetapiisinstance
bersama dengan ABC memberikan solusi bersih.Namun, saya setuju bahwa dalam kebanyakan situasi
hasattr
pendekatan (dijelaskan dalam jawaban lain) adalah solusi yang paling tepat.sumber
Harap Anda mengharapkan hasattr (), tetapi cobalah untuk menghindari hasattr () dan lebih suka getattr (). getattr () lebih cepat dari hasattr ()
menggunakan hasattr ():
sama di sini saya menggunakan getattr untuk mendapatkan properti jika tidak ada properti itu tidak mengembalikan apa pun
sumber
EDIT : Pendekatan ini memiliki batasan serius. Ini harus bekerja jika objek itu objek yang dapat diubah . Silakan periksa komentar di bawah ini.
Jika Anda menggunakan Python 3.6 atau lebih tinggi seperti saya, ada alternatif yang nyaman untuk memeriksa apakah suatu objek memiliki atribut tertentu:
Namun, saya tidak yakin mana yang merupakan pendekatan terbaik saat ini. menggunakan
hasattr()
, menggunakangetattr()
atau menggunakanin
. Komentar diterima.sumber
in
kata kunci berfungsi untuk memeriksa jenis yang dapat diubah. Misalnya,'foo' in None
melempar kesalahanTypeError: argument of type 'NoneType' is not iterable
. Cara mengatasinya adalah untuk memeriksa apakah jenisnya dapat diubah sebelum digunakanin
. Setelah mengoreksi kasus tepi seperti jenis yang tidak dapat diubah, Anda mungkin lebih baik menggunakanhasattr()
karena dirancang untuk menangani kasus tepi.dict
sebagai "objek ringan", mirip dengan desain objek JavaScript, tetapi sebagian besar kelas normal tidak akan mendukung ini secara umum (mendapatkan varian pada kesalahan yang disebutkan oleh @SethDifley) .Inilah pendekatan yang sangat intuitif:
sumber
Ini super sederhana, cukup gunakan
dir(
objek.)
Ini akan mengembalikan daftar setiap fungsi dan atribut objek yang tersedia.
sumber
Opsi lain yang mungkin, tetapi itu tergantung jika apa yang Anda maksudkan sebelumnya :
keluaran:
Ini memungkinkan Anda bahkan memeriksa atribut Tidak Ada yang dihargai.
Tapi! Berhati-hatilah, Anda tidak sengaja membuat instance dan membandingkan
undefined
beberapa tempat karenais
itu tidak akan pernah berfungsi dalam kasus itu.Memperbarui:
karena apa yang saya peringatkan di paragraf di atas, memiliki banyak undefined yang tidak pernah cocok, saya baru saja sedikit mengubah pola ini:
undefined = NotImplemented
NotImplemented
, jangan bingung denganNotImplementedError
, adalah built-in: itu semi-cocok dengan maksud JSundefined
dan Anda dapat menggunakan kembali definisi di mana-mana dan itu akan selalu cocok. Kelemahannya adalah "benar" di boolean dan bisa terlihat aneh di log dan tumpukan jejak (tapi Anda cepat mengatasinya ketika Anda tahu itu hanya muncul dalam konteks ini).sumber
Anda dapat memeriksa apakah
object
mengandung atribut dengan menggunakanhasattr
metode builtin.Misalnya jika objek
a
Anda dan Anda ingin memeriksa atributstuff
Metode signature itu sendiri
hasattr(object, name) -> bool
yang berarti jikaobject
memiliki atribut yang diteruskan ke argumen keduahasattr
daripada memberikan booleanTrue
atauFalse
sesuai dengan keberadaanname
atribut dalam objek.sumber
hasattr()
adalah jawaban yang tepat. Yang ingin saya tambahkan adalah yanghasattr()
juga dapat digunakan dengan baik bersama penegasan (untuk menghindariif
pernyataan yang tidak perlu dan membuat kode lebih mudah dibaca):Sebagaimana dinyatakan dalam jawaban lain pada SO : Asserts harus digunakan untuk menguji kondisi yang seharusnya tidak pernah terjadi. Tujuannya adalah untuk crash awal dalam kasus program yang korup.
sumber
hasattr
bukan kode sekitarnya.