Saya akan mengatakan Anda (OP) pasti harus membaca tautan yang direferensikan, yang memberikan banyak detail mengapa memeriksa jenis objek biasanya merupakan ide yang buruk, dan apa yang seharusnya Anda lakukan.
Jeff Shannon
2
Anda harus menggunakan basestr, bukan str. jika tidak, Anda tidak akan memilih unicode. (meskipun untuk 3.x saya pikir str adalah yang basestr)
Hasen
36
isinstance bekerja:
if isinstance(obj,MyClass): do_foo(obj)
tetapi , perlu diingat: jika itu terlihat seperti bebek, dan jika itu terdengar seperti bebek, itu adalah bebek.
Sunting: Untuk jenis Tidak Ada, Anda cukup melakukan:
def distance_from_zero(n): if isinstance(n,int) or isinstance(n,float): return abs(n) else: return "Nope" print distance_from_zero(True) Ini mengembalikan "1" bukannya "Tidak". Bagaimana menyiasatinya?
dig_123
Jika Anda ingin menggunakan isinstancetetapi periksa juga untuk Nonekemudian isinstance(obj, (MyClass, type(None)))berfungsi. types.NoneTypetelah dihapus dari Python 3 sehingga tidak portabel type(None)untuk mendapatkan referensi NoneType.
Santeri Paavolainen
33
Pertama, hindari semua perbandingan tipe. Mereka sangat, sangat jarang diperlukan. Terkadang, mereka membantu memeriksa tipe parameter dalam suatu fungsi - bahkan itu jarang terjadi. Jenis data yang salah akan menimbulkan pengecualian, dan hanya itu yang Anda perlukan.
Semua fungsi konversi dasar akan dipetakan sama dengan fungsi tipe.
type(9)is int
type(2.5)is float
type('x')is str
type(u'x')is unicode
type(2+3j)is complex
Tidak ada, BTW, tidak pernah membutuhkan jenis pemeriksaan semacam ini. Tidak ada satu-satunya contoh dari NoneType. Objek None adalah Singleton. Cukup periksa Tidak Ada
variable isNone
BTW, jangan gunakan di atas secara umum. Gunakan pengecualian biasa dan polimorfisme alami Python sendiri.
Jika Anda memvalidasi input dari DSL, Anda memerlukan semua ini, bahkan NoneType. Bagaimana jika parameter bisa menjadi str, unicodeatau None? isinstance(x, (str, unicode, types.NoneType))jauh lebih bersih daripada memeriksa None. Jika Anda membuat alat untuk perhitungan yang ditunda, atau jika Anda akan meluncurkan proses yang panjang atau padat sumber daya, penting untuk menangkap typekesalahan sebelumnya, selama beberapa langkah validasi khusus. Ini telah menjadi bagian penting dari hampir setiap proyek komputasi ilmiah yang pernah saya kerjakan. Dari semua proyek dev yang saya lihat, lebih banyak membutuhkan ini daripada tidak.
>>>import types
>>> x ="mystring">>> isinstance(x, types.StringType)True>>> x =5>>> isinstance(x, types.IntType)True>>> x =None>>> isinstance(x, types.NoneType)True
Anda selalu dapat menggunakan type(x) == type(y)triknya, di mana yada sesuatu dengan tipe yang dikenal.
# check if x is a regular string
type(x)== type('')# check if x is an integer
type(x)== type(1)# check if x is a NoneType
type(x)== type(None)
Seringkali ada cara yang lebih baik untuk melakukan itu, terutama dengan python baru-baru ini. Tetapi jika Anda hanya ingin mengingat satu hal, Anda dapat mengingatnya.
Dalam hal ini, cara yang lebih baik adalah:
# check if x is a regular string
type(x)== str
# check if x is either a regular string or a unicode string
type(x)in[str, unicode]# alternatively:
isinstance(x, basestring)# check if x is an integer
type(x)== int
# check if x is a NoneType
x isNone
Perhatikan kasus terakhir: hanya ada satu instance NoneTypedi python, dan itu adalah None. Anda akan melihat NoneType banyak dalam pengecualian ( TypeError: 'NoneType' object is unsubscriptable- terjadi pada saya sepanjang waktu ..) tetapi Anda hampir tidak pernah perlu merujuknya dalam kode.
Akhirnya, seperti yang ditunjukkan fengshaun, mengetik memeriksa python tidak selalu merupakan ide yang baik. Lebih pythonic untuk hanya menggunakan nilai seolah-olah itu adalah tipe yang Anda harapkan, dan menangkap (atau memungkinkan untuk diperbanyak) pengecualian yang dihasilkan dari itu.
Untuk apa nilainya, isinstance () adalah cara yang disukai untuk memeriksa jenis dalam Python (ketika Anda harus melakukannya).
David Z
6
Anda sangat dekat! stringadalah modul, bukan tipe. Anda mungkin ingin membandingkan jenis objterhadap objek tipe untuk string, yaitu str:
type(obj)== str # this works because str is already a type
Kalau tidak:
type(obj)== type('')
Catatan, dalam Python 2, jika objmerupakan tipe unicode, maka tak satu pun dari yang di atas akan berfungsi. Tidak akan isinstance(). Lihat komentar John pada postingan ini untuk mengetahui bagaimana caranya ... Saya sudah mencoba mengingatnya sekitar 10 menit sekarang, tetapi mengalami blok memori!
Gunakan basestring dengan isinstance () untuk mendapatkan str dan unicode.
John Fouhy
5
Itu karena Anda harus menulis
s="hello"
type(s)== type("")
ketik menerima sebuah instance dan mengembalikan tipenya. Dalam hal ini Anda harus membandingkan dua tipe instance.
Jika Anda perlu melakukan pemeriksaan preemptive, lebih baik jika Anda memeriksa antarmuka yang didukung daripada jenisnya.
Tipe ini tidak terlalu banyak memberi tahu Anda, terlepas dari kenyataan bahwa kode Anda menginginkan instance dari tipe tertentu, terlepas dari fakta bahwa Anda dapat memiliki instance lain dari tipe yang sama sekali berbeda yang akan sangat baik karena mengimplementasikan antarmuka yang sama .
Misalnya, anggap Anda memiliki kode ini
def firstElement(parameter):return parameter[0]
Sekarang, anggaplah Anda berkata: Saya ingin kode ini hanya menerima tuple.
import types
def firstElement(parameter):if type(parameter)!= types.TupleType:raiseTypeError("function accepts only a tuple")return parameter[0]
Ini mengurangi penggunaan kembali rutin ini. Ini tidak akan berfungsi jika Anda melewati daftar, atau string, atau numpy.array. Sesuatu yang lebih baik
tetapi tidak ada gunanya melakukannya: parameter [0] akan memunculkan pengecualian jika protokolnya tidak terpenuhi ... ini tentu saja kecuali Anda ingin mencegah efek samping atau harus memulihkan dari panggilan yang dapat Anda panggil sebelum gagal. Contoh (bodoh), hanya untuk menjelaskan:
dalam hal ini, kode Anda akan menimbulkan pengecualian sebelum menjalankan panggilan sistem (). Tanpa pemeriksaan antarmuka, Anda akan menghapus file tersebut, dan kemudian mengangkat pengecualian.
Terima kasih telah menunjukkan cara yang lebih disukai yang sebenarnya untuk memeriksa antarmuka. Banyak jawaban di sini yang menyebutkannya, tetapi hanya sedikit yang memberikan contoh tentang apa yang baik. Itu masih tidak menjawab pertanyaan pribadi saya secara langsung (saya mencoba untuk memisahkan daftar string, berisi banyak item yang bermakna, dari string, yang berisi banyak item, bukan item yang bermakna. Terima kasih!
Nick
5
Gunakan str sebagai ganti string
type ( obj )== str
Penjelasan
>>> a ="Hello">>> type(a)==str
True>>> type(a)<type 'str'>>>>
Hah? mengapa itu ide yang buruk secara umum? Ini hanya ide yang buruk untuk string (untuk pra 3.0) karena ada dua jenis string, str dan unicode. Untuk array, itu ide bagus.
hasen
@ Hasen: ini adalah ide buruk secara keseluruhan. Bagaimana jika saya mendefinisikan tipe saya sendiri yang berperilaku seperti array tetapi, katakanlah, mengambil nilai dari database? Kode Anda akan gagal dengan tipeku tanpa alasan.
Nah, seluruh alasan (bagi saya setidaknya) dalam memeriksa tipe persis karena saya ingin berurusan dengan array berbeda dari tipe lain (termasuk tipe yang meniru array).
Hasen
2
Anda salah. Saya akan memberikan Anda contoh konkret: Django memiliki shortcut rendering template yang dapat menerima string atau array string. Sekarang, baik string dan array (daftar) dapat diubah, tetapi dalam kasus ini, fungsi-fungsi perlu dibedakan di antara mereka.
Untuk mendapatkan tipe, gunakan __class__anggota, seperti padaunknown_thing.__class__
Bicara tentang mengetik bebek tidak berguna di sini karena tidak menjawab pertanyaan yang sangat bagus. Dalam kode aplikasi saya, saya tidak pernah perlu mengetahui jenis sesuatu, tetapi masih bermanfaat untuk memiliki cara mempelajari jenis objek. Kadang-kadang saya perlu mendapatkan kelas aktual untuk memvalidasi tes unit. Mengetik bebek menghalangi jalan karena semua objek yang mungkin memiliki API yang sama, tetapi hanya satu yang benar. Juga, kadang-kadang saya menjaga kode orang lain, dan saya tidak tahu objek apa yang telah saya lewati. Ini adalah masalah terbesar saya dengan bahasa yang diketik secara dinamis seperti Python. Versi 1 sangat mudah dan cepat untuk dikembangkan. Versi 2 sangat menyusahkan roti, terutama jika Anda tidak menulis versi 1. Jadi, kadang-kadang, ketika saya bekerja dengan fungsi yang tidak saya tulis, saya perlu tahu jenis parameternya,
Di situlah __class__parameter berguna. Itu (sejauh yang saya tahu) adalah cara terbaik (mungkin satu-satunya cara) untuk mendapatkan jenis objek.
Gunakan isinstance(object, type). Seperti di atas ini mudah digunakan jika Anda tahu yang benar type, misalnya,
isinstance('dog', str)## gives bool True
Tetapi untuk objek yang lebih esoteris, ini bisa sulit digunakan. Sebagai contoh:
import numpy as np
a = np.array([1,2,3])
isinstance(a,np.array)## breaks
tetapi Anda dapat melakukan trik ini:
y = type(np.array([1]))
isinstance(a,y)## gives bool True
Jadi saya sarankan instantiating variabel ( ydalam hal ini) dengan jenis objek yang ingin Anda periksa (misalnya, type(np.array())), kemudian gunakan isinstance.
type(obj) == str
Jawaban:
Dalam kasus Anda,
isinstance("this is a string", str)
akan kembaliTrue
.Anda mungkin juga ingin membaca ini: http://www.canonical.org/~kragen/isinstance/
sumber
isinstance
bekerja:tetapi , perlu diingat: jika itu terlihat seperti bebek, dan jika itu terdengar seperti bebek, itu adalah bebek.
Sunting: Untuk jenis Tidak Ada, Anda cukup melakukan:
sumber
def distance_from_zero(n): if isinstance(n,int) or isinstance(n,float): return abs(n) else: return "Nope" print distance_from_zero(True)
Ini mengembalikan "1" bukannya "Tidak". Bagaimana menyiasatinya?isinstance
tetapi periksa juga untukNone
kemudianisinstance(obj, (MyClass, type(None)))
berfungsi.types.NoneType
telah dihapus dari Python 3 sehingga tidak portabeltype(None)
untuk mendapatkan referensiNoneType
.Pertama, hindari semua perbandingan tipe. Mereka sangat, sangat jarang diperlukan. Terkadang, mereka membantu memeriksa tipe parameter dalam suatu fungsi - bahkan itu jarang terjadi. Jenis data yang salah akan menimbulkan pengecualian, dan hanya itu yang Anda perlukan.
Semua fungsi konversi dasar akan dipetakan sama dengan fungsi tipe.
Ada beberapa kasus lain.
Tidak ada, BTW, tidak pernah membutuhkan jenis pemeriksaan semacam ini. Tidak ada satu-satunya contoh dari NoneType. Objek None adalah Singleton. Cukup periksa Tidak Ada
BTW, jangan gunakan di atas secara umum. Gunakan pengecualian biasa dan polimorfisme alami Python sendiri.
sumber
NoneType
. Bagaimana jika parameter bisa menjadistr
,unicode
atauNone
?isinstance(x, (str, unicode, types.NoneType))
jauh lebih bersih daripada memeriksaNone
. Jika Anda membuat alat untuk perhitungan yang ditunda, atau jika Anda akan meluncurkan proses yang panjang atau padat sumber daya, penting untuk menangkaptype
kesalahan sebelumnya, selama beberapa langkah validasi khusus. Ini telah menjadi bagian penting dari hampir setiap proyek komputasi ilmiah yang pernah saya kerjakan. Dari semua proyek dev yang saya lihat, lebih banyak membutuhkan ini daripada tidak.Untuk jenis lain, lihat modul jenis :
PS Typechecking adalah ide yang buruk.
sumber
Anda selalu dapat menggunakan
type(x) == type(y)
triknya, di manay
ada sesuatu dengan tipe yang dikenal.Seringkali ada cara yang lebih baik untuk melakukan itu, terutama dengan python baru-baru ini. Tetapi jika Anda hanya ingin mengingat satu hal, Anda dapat mengingatnya.
Dalam hal ini, cara yang lebih baik adalah:
Perhatikan kasus terakhir: hanya ada satu instance
NoneType
di python, dan itu adalahNone
. Anda akan melihat NoneType banyak dalam pengecualian (TypeError: 'NoneType' object is unsubscriptable
- terjadi pada saya sepanjang waktu ..) tetapi Anda hampir tidak pernah perlu merujuknya dalam kode.Akhirnya, seperti yang ditunjukkan fengshaun, mengetik memeriksa python tidak selalu merupakan ide yang baik. Lebih pythonic untuk hanya menggunakan nilai seolah-olah itu adalah tipe yang Anda harapkan, dan menangkap (atau memungkinkan untuk diperbanyak) pengecualian yang dihasilkan dari itu.
sumber
Anda sangat dekat!
string
adalah modul, bukan tipe. Anda mungkin ingin membandingkan jenisobj
terhadap objek tipe untuk string, yaitustr
:Kalau tidak:
Catatan, dalam Python 2, jika
obj
merupakan tipe unicode, maka tak satu pun dari yang di atas akan berfungsi. Tidak akanisinstance()
. Lihat komentar John pada postingan ini untuk mengetahui bagaimana caranya ... Saya sudah mencoba mengingatnya sekitar 10 menit sekarang, tetapi mengalami blok memori!sumber
Itu karena Anda harus menulis
ketik menerima sebuah instance dan mengembalikan tipenya. Dalam hal ini Anda harus membandingkan dua tipe instance.
Jika Anda perlu melakukan pemeriksaan preemptive, lebih baik jika Anda memeriksa antarmuka yang didukung daripada jenisnya.
Tipe ini tidak terlalu banyak memberi tahu Anda, terlepas dari kenyataan bahwa kode Anda menginginkan instance dari tipe tertentu, terlepas dari fakta bahwa Anda dapat memiliki instance lain dari tipe yang sama sekali berbeda yang akan sangat baik karena mengimplementasikan antarmuka yang sama .
Misalnya, anggap Anda memiliki kode ini
Sekarang, anggaplah Anda berkata: Saya ingin kode ini hanya menerima tuple.
Ini mengurangi penggunaan kembali rutin ini. Ini tidak akan berfungsi jika Anda melewati daftar, atau string, atau numpy.array. Sesuatu yang lebih baik
tetapi tidak ada gunanya melakukannya: parameter [0] akan memunculkan pengecualian jika protokolnya tidak terpenuhi ... ini tentu saja kecuali Anda ingin mencegah efek samping atau harus memulihkan dari panggilan yang dapat Anda panggil sebelum gagal. Contoh (bodoh), hanya untuk menjelaskan:
dalam hal ini, kode Anda akan menimbulkan pengecualian sebelum menjalankan panggilan sistem (). Tanpa pemeriksaan antarmuka, Anda akan menghapus file tersebut, dan kemudian mengangkat pengecualian.
sumber
Gunakan str sebagai ganti string
Penjelasan
sumber
saya menggunakan
type(x) == type(y)
Misalnya, jika saya ingin memeriksa sesuatu adalah array:
periksa string:
Jika Anda ingin memeriksa Tidak ada, gunakan adalah
sumber
Saya pikir ini harus dilakukan
sumber
Ketik tidak berfungsi pada kelas-kelas tertentu. Jika Anda tidak yakin dengan jenis objek gunakan
__class__
metode, seperti:Lihat juga artikel ini - http://www.siafoo.net/article/56
sumber
Untuk mendapatkan tipe, gunakan
__class__
anggota, seperti padaunknown_thing.__class__
Bicara tentang mengetik bebek tidak berguna di sini karena tidak menjawab pertanyaan yang sangat bagus. Dalam kode aplikasi saya, saya tidak pernah perlu mengetahui jenis sesuatu, tetapi masih bermanfaat untuk memiliki cara mempelajari jenis objek. Kadang-kadang saya perlu mendapatkan kelas aktual untuk memvalidasi tes unit. Mengetik bebek menghalangi jalan karena semua objek yang mungkin memiliki API yang sama, tetapi hanya satu yang benar. Juga, kadang-kadang saya menjaga kode orang lain, dan saya tidak tahu objek apa yang telah saya lewati. Ini adalah masalah terbesar saya dengan bahasa yang diketik secara dinamis seperti Python. Versi 1 sangat mudah dan cepat untuk dikembangkan. Versi 2 sangat menyusahkan roti, terutama jika Anda tidak menulis versi 1. Jadi, kadang-kadang, ketika saya bekerja dengan fungsi yang tidak saya tulis, saya perlu tahu jenis parameternya,
Di situlah
__class__
parameter berguna. Itu (sejauh yang saya tahu) adalah cara terbaik (mungkin satu-satunya cara) untuk mendapatkan jenis objek.sumber
Gunakan
isinstance(object, type)
. Seperti di atas ini mudah digunakan jika Anda tahu yang benartype
, misalnya,Tetapi untuk objek yang lebih esoteris, ini bisa sulit digunakan. Sebagai contoh:
tetapi Anda dapat melakukan trik ini:
Jadi saya sarankan instantiating variabel (
y
dalam hal ini) dengan jenis objek yang ingin Anda periksa (misalnya,type(np.array())
), kemudian gunakanisinstance
.sumber
Anda dapat membandingkan kelas untuk level pemeriksaan.
sumber