Dengan python, apa cara terbaik untuk menguji apakah suatu variabel berisi daftar atau tupel? (mis. koleksi)
Apakah isinstance()
seburuk yang disarankan di sini? http://www.canonical.org/~kragen/isinstance/
Pembaruan: alasan paling umum saya ingin membedakan daftar dari string adalah ketika saya memiliki beberapa pohon bersarang / struktur data dari daftar daftar string dll. Yang saya jelajahi dengan algoritma rekursif dan saya perlu untuk mengetahui kapan saya telah menekan node "leaf".
Jawaban:
Silakan dan gunakan
isinstance
jika Anda membutuhkannya. Ini agak jahat, karena tidak termasuk urutan kustom, iterator, dan hal-hal lain yang mungkin benar-benar Anda butuhkan. Namun, terkadang Anda perlu berperilaku berbeda jika seseorang, misalnya, melewatkan sebuah string. Preferensi saya ada untuk secara eksplisit memeriksastr
atauunicode
seperti:NB Jangan salah
types.StringType
untuktypes.StringTypes
. Yang terakhir menggabungkanstr
danunicode
objek.The
types
Modul dianggap oleh banyak untuk menjadi usang dalam mendukung hanya memeriksa secara langsung terhadap jenis objek, jadi jika Anda lebih suka tidak menggunakan atas, Anda alternatif dapat memeriksa secara eksplisit terhadapstr
danunicode
, seperti ini:Edit:
Lebih baik lagi adalah:
Akhiri edit
Setelah salah satu dari ini, Anda dapat kembali berperilaku seolah-olah Anda mendapatkan urutan normal, membiarkan non-urutan meningkatkan pengecualian yang sesuai.
Melihat hal yang "jahat" tentang pengecekan tipe bukanlah bahwa Anda mungkin ingin berperilaku berbeda untuk jenis objek tertentu, itu adalah bahwa Anda secara artifisial membatasi fungsi Anda dari melakukan hal yang benar dengan jenis objek yang tidak terduga yang sebaliknya akan melakukan hal yang benar. Jika Anda memiliki fallback terakhir yang tidak dicentang, Anda menghapus batasan ini. Perlu dicatat bahwa pengecekan tipe terlalu banyak adalah bau kode yang menunjukkan bahwa Anda mungkin ingin melakukan beberapa refactoring, tetapi itu tidak berarti Anda harus menghindarinya dari getgo.
sumber
str
jenisnya, Anda harus menggunakannya secara langsung, alih-alih menggunakantypes.StringType
yang hanya merupakan alias untuk itu. Tapi saya kira jawaban ini tidak menjawab pertanyaan seperti yang diajukan, karena itu tentang "koleksi". Kecuali Anda menggunakan python yang cukup baru untuk memilikiabc
modul itu bukan sesuatu yang dapat Anda gunakanisinstance
untuk memeriksa, dan bahkan kemudian saya akan merekomendasikan menghindari pemeriksaan jika memungkinkan.assert isinstance(u'abc', str) == False
. Saya setuju bahwa lebih baik untuk memeriksa jenisnya secara langsung, daripada menggunakantypes
modul, tetapitypes.StringTypes
melakukan sesuatu yangstr
tidak: ia mengembalikan True untukstr
danunicode
objek. Saya akan mengedit respons saya untuk menawarkan pemeriksaan ganda sebagai alternatif.isinstance
kejahatan?" Dan saya memberikan contoh balasan yang (1) penggunaannya tidak jahatisinstance
, karena mundur berarti tidak merusak ducktyping, dan (2) merupakan solusi yang baik untuk motivasi yang sangat umum dimiliki orang-orang karena ingin memeriksa apakah sesuatu adalah alist
atautuple
(yaitu untuk mendamaikan mereka dari string).class Foo(str): pass
melakukan yang Anda inginkan?sumber
type([]) is list
pengembalianTrue
type(x) in [list,tuple]
lebih pendek.Tidak ada yang salah dengan menggunakan
isinstance
selama itu tidak berlebihan. Jika suatu variabel hanya berupa daftar / tuple maka dokumentasikan antarmuka dan gunakan saja seperti itu. Kalau tidak, cek itu masuk akal:Jenis pemeriksaan ini memang memiliki beberapa kasus penggunaan yang baik, seperti dengan metode string startswith / endswith standar (meskipun untuk lebih akuratnya ini diimplementasikan dalam C di CPython menggunakan pemeriksaan eksplisit untuk melihat apakah itu tuple - ada lebih dari satu cara untuk menyelesaikan masalah ini, sebagaimana disebutkan dalam artikel yang Anda tautkan).
Pemeriksaan eksplisit seringkali lebih baik daripada mencoba menggunakan objek sebagai wadah dan menangani pengecualian - yang dapat menyebabkan semua jenis masalah dengan kode yang dijalankan sebagian atau tidak perlu.
sumber
set
objek juga merupakan iterable, yang berarti bahwa meskipun Anda pasti dapat memunculkan elemen darinya, tetapi itu tidak menjamin urutan tertentu, yang merupakan hal yang sangat berbahaya untuk algoritma tertentu. Dalam kasus ketika pemesanan elemen tidak masalah, sebuah algoritma yang menggunakan potongan ini berpotensi menghasilkan hasil yang berbeda pada proses yang berbeda!Dokumentasikan argumen itu sebagai perlu urutan, dan gunakan sebagai urutan. Jangan periksa tipenya.
sumber
Bagaimana dengan
hasattr(a, "__iter__")
:?Ia memberi tahu jika objek yang dikembalikan dapat diulang sebagai generator. Secara default, tupel dan daftar bisa, tetapi bukan tipe string.
sumber
__iter__
.__iter__
karena suatu alasan ...Pada Python 2.8
type(list) is list
kembalifalse
saya sarankan membandingkan jenis dengan cara yang mengerikan ini:
(setidaknya pada sistem saya, menggunakan anaconda pada Mac OS X Yosemite)
sumber
type(list) is list
kembaliFalse
karenatype(list)
initype
, tidaklist
.type(list()) is list
atau dengan contoh daftar lainnya akan kembaliTrue
.Python menggunakan "Bebek mengetik", yaitu jika variabel kwaks seperti bebek, itu harus bebek. Dalam kasus Anda, Anda mungkin ingin iterable, atau Anda ingin mengakses item pada indeks tertentu. Anda hanya harus melakukan ini: yaitu menggunakan objek di dalam
for var:
atauvar[idx]
di dalamtry
blok, dan jika Anda mendapatkan pengecualian itu bukan bebek ...sumber
var
iterasi string akan terjadi dengan hasil yang mungkin tidak terduga.sumber
Jika Anda hanya perlu tahu apakah Anda dapat menggunakan
foo[123]
notasi dengan variabel, Anda dapat memeriksa keberadaan__getitem__
atribut (yang disebut panggilan python saat Anda mengakses dengan indeks) denganhasattr(foo, '__getitem__')
sumber
Harus menjadi tes yang lebih kompleks jika Anda benar-benar ingin menangani apa saja sebagai argumen fungsi.
Meskipun, biasanya itu cukup dengan hanya mengeja bahwa suatu fungsi mengharapkan iterable dan kemudian periksa saja
type(a) != type('')
.Juga mungkin terjadi bahwa untuk string Anda memiliki jalur pemrosesan yang sederhana atau Anda akan bersikap baik dan melakukan split dll, jadi Anda tidak ingin berteriak pada string dan jika seseorang mengirimi Anda sesuatu yang aneh, biarkan saja ia memiliki pengecualian.
sumber
Cara mudah lain untuk mengetahui apakah suatu variabel adalah list atau tuple atau umumnya memeriksa tipe variabel adalah:
sumber
Pada prinsipnya, saya setuju dengan Ignacio, di atas, tetapi Anda juga dapat menggunakan tipe untuk memeriksa apakah ada tupel atau daftar.
sumber