Dalam Python 3, semua string adalah urutan karakter Unicode. Ada bytestipe yang menyimpan byte mentah.
Dalam Python 2, sebuah string dapat berupa tipe stratau tipe unicode. Anda dapat mengetahui kode mana yang menggunakan sesuatu seperti ini:
def whatisthis(s):if isinstance(s, str):print"ordinary string"elif isinstance(s, unicode):print"unicode string"else:print"not a string"
Ini tidak membedakan "Unicode atau ASCII"; itu hanya membedakan tipe Python. String Unicode dapat terdiri dari karakter murni dalam rentang ASCII, dan bytestring dapat berisi ASCII, Unicode yang dikodekan, atau bahkan data non-tekstual.
Dalam Python 2, strhanya urutan byte. Python tidak tahu apa penyandiannya. The unicodejenis adalah cara yang lebih aman untuk menyimpan teks. Jika Anda ingin lebih memahami ini, saya sarankan http://farmdev.com/talks/unicode/ .
Dalam Python 3, strseperti Python 2 unicode, dan digunakan untuk menyimpan teks. Apa yang disebut strdengan Python 2 disebut bytesdengan Python 3.
Bagaimana cara mengetahui apakah sebuah byte string valid atau 8 atau ascii
Anda bisa menelepon decode. Jika itu memunculkan eksepsi UnicodeDecodeError, itu tidak valid.
>>> u_umlaut = b'\xc3\x9c'# UTF-8 representation of the letter 'Ü'>>> u_umlaut.decode('utf-8')
u'\xdc'>>> u_umlaut.decode('ascii')Traceback(most recent call last):File"<stdin>", line 1,in<module>UnicodeDecodeError:'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
Hanya untuk referensi orang lain - str.decode tidak tidak ada dalam python 3. Sepertinya Anda harus melakukan unicode(s, "ascii")sesuatu
Shadow
3
Maaf, maksud sayastr(s, "ascii")
Shadow
1
Ini tidak akurat untuk python 3
ProsperousHeart
2
@ProsperousHeart Diperbarui untuk mencakup Python 3. Dan untuk mencoba menjelaskan perbedaan antara bytestrings dan string unicode.
Mikel
44
Dalam python 3.x semua string adalah urutan karakter Unicode. dan melakukan isinstance check untuk str (yang berarti string unicode secara default) sudah cukup.
isinstance(x, str)
Sehubungan dengan python 2.x, Kebanyakan orang tampaknya menggunakan pernyataan if yang memiliki dua pemeriksaan. satu untuk str dan satu untuk unicode.
Jika Anda ingin memeriksa apakah Anda memiliki objek 'string-like' semua dengan satu pernyataan, Anda dapat melakukan hal berikut:
Ini salah. Dalam Python 2.7 isinstance(u"x",basestring)kembali True.
PythonNut
11
@PythonNut: Saya yakin itulah intinya. Penggunaan isinstance (x, basestring) sudah cukup untuk menggantikan tes ganda yang berbeda di atas.
KQ.
5
Ini berguna dalam banyak kasus, tetapi jelas bukan yang dimaksud si penanya.
mhsmith
3
Ini adalah jawaban untuk pertanyaan itu. Semua yang lain salah memahami apa yang dikatakan OP dan memberikan jawaban umum tentang jenis pemeriksaan dengan Python.
fiatjaf
1
Tidak menjawab pertanyaan OP. Judul pertanyaan (sendiri) BISA diinterpretasikan sedemikian rupa sehingga jawaban ini benar. Namun, OP secara khusus mengatakan "mencari tahu mana" dalam deskripsi pertanyaan, dan jawaban ini tidak membahasnya.
MD004
31
Unicode bukan pengodean - mengutip Kumar McMillan:
Jika ASCII, UTF-8, dan string byte lainnya adalah "teks" ...
... maka Unicode adalah "text-ness";
itu adalah bentuk abstrak dari teks
Telah membaca tentang McMillan's Unicode In Python, bicara Sepenuhnya Demystified dari PyCon 2008, itu menjelaskan banyak hal lebih baik daripada sebagian besar jawaban terkait pada Stack Overflow.
Slide-slide itu mungkin adalah pengantar terbaik untuk Unicode yang pernah saya temui
Jonny
23
Jika kebutuhan kode Anda agar kompatibel dengan kedua Python 2 dan Python 3, Anda tidak bisa langsung menggunakan hal-hal seperti isinstance(s,bytes)atau isinstance(s,unicode)tanpa membungkus mereka baik mencoba / kecuali atau tes versi python, karena bytestidak terdefinisi dengan Python 2 dan unicodetidak terdefinisi di Python 3 .
Ada beberapa solusi buruk. Yang sangat jelek adalah membandingkan nama tipe, bukan membandingkan tipe itu sendiri. Ini sebuah contoh:
# convert bytes (python 3) or unicode (python 2) to strif str(type(s))=="<class 'bytes'>":# only possible in Python 3
s = s.decode('ascii')# or s = str(s)[2:-1]elif str(type(s))=="<type 'unicode'>":# only possible in Python 2
s = str(s)
Solusi yang bisa dibilang sedikit kurang jelek adalah memeriksa nomor versi Python, misalnya:
if sys.version_info >=(3,0,0):# for Python 3if isinstance(s, bytes):
s = s.decode('ascii')# or s = str(s)[2:-1]else:# for Python 2if isinstance(s, unicode):
s = str(s)
Keduanya unpythonic, dan sebagian besar waktu mungkin ada cara yang lebih baik.
Cara yang lebih baik mungkin adalah dengan menggunakan six, dan uji terhadap six.binary_typedansix.text_type
Ian Clelland
1
Anda dapat menggunakan jenis .__ nama__ untuk menyelidiki nama jenis.
Paulo Freitas
Saya tidak begitu yakin kasus penggunaan untuk sedikit kode, kecuali ada kesalahan logika. Saya pikir harus ada "tidak" dalam kode python 2. Kalau tidak, Anda mengubah segalanya menjadi string unicode untuk Python 3 dan sebaliknya untuk Python 2!
oligofren
Ya, oligofren, itulah fungsinya. String internal standar adalah Unicode dalam Python 3 dan ASCII dalam Python 2. Jadi potongan kode mengkonversi teks ke tipe string internal standar (baik itu Unicode atau ASCII).
Dave Burton
12
menggunakan:
import six
if isinstance(obj, six.text_type)
di dalam enam perpustakaan direpresentasikan sebagai:
if PY3:
string_types = str,else:
string_types = basestring,
seharusnya begitu if isinstance(obj, six.text_type) . Tapi ya ini adalah jawaban yang benar.
karantan
Tidak menjawab pertanyaan OP. Judul pertanyaan (sendiri) BISA diinterpretasikan sedemikian rupa sehingga jawaban ini benar. Namun, OP secara khusus mengatakan "mencari tahu mana" dalam deskripsi pertanyaan, dan jawaban ini tidak membahasnya.
MD004
4
Perhatikan bahwa pada Python 3, tidak adil untuk mengatakan:
strs adalah UTFx untuk x (mis. UTF8)
strIni adalah Unicode
strs adalah koleksi karakter Unicode yang dipesan
strJenis Python adalah (biasanya) urutan titik kode Unicode, beberapa di antaranya memetakan karakter.
Bahkan di Python 3, tidak semudah menjawab pertanyaan ini seperti yang Anda bayangkan.
Cara yang jelas untuk menguji string yang kompatibel dengan ASCII adalah dengan mencoba penyandian:
"Hello there!".encode("ascii")#>>> b'Hello there!'"Hello there... ☃!".encode("ascii")#>>> Traceback (most recent call last):#>>> File "", line 4, in <module>#>>> UnicodeEncodeError: 'ascii' codec can't encode character '\u2603' in position 15: ordinal not in range(128)
Kesalahan membedakan kasus.
Di Python 3, bahkan ada beberapa string yang berisi poin kode Unicode yang tidak valid:
"Hello there!".encode("utf8")#>>> b'Hello there!'"\udcc3".encode("utf8")#>>> Traceback (most recent call last):#>>> File "", line 19, in <module>#>>> UnicodeEncodeError: 'utf-8' codec can't encode character '\udcc3' in position 0: surrogates not allowed
Metode yang sama untuk membedakan mereka digunakan.
Ini dapat membantu orang lain, saya memulai pengujian untuk tipe string dari variabel s, tetapi untuk aplikasi saya, lebih masuk akal untuk mengembalikan s sebagai utf-8. Proses memanggil return_utf, kemudian tahu apa yang ia hadapi dan dapat menangani string dengan tepat. Kode ini tidak asli, tetapi saya bermaksud untuk menjadi agnostik versi Python tanpa tes versi atau mengimpor enam. Berikan komentar dengan penyempurnaan kode contoh di bawah ini untuk membantu orang lain.
def return_utf(s):if isinstance(s, str):return s.encode('utf-8')if isinstance(s,(int, float, complex)):return str(s).encode('utf-8')try:return s.encode('utf-8')exceptTypeError:try:return str(s).encode('utf-8')exceptAttributeError:return s
exceptAttributeError:return s
return s # assume it was already utf-8
Anda, teman saya, layak mendapat jawaban yang benar! Saya menggunakan python 3 dan saya masih mengalami masalah sampai saya menemukan harta ini!
mnsr
2
Anda dapat menggunakan Universal Encoding Detector , tetapi ketahuilah bahwa itu hanya akan memberi Anda tebakan terbaik, bukan pengkodean yang sebenarnya, karena tidak mungkin untuk mengetahui pengkodean string "abc" misalnya. Anda perlu mendapatkan informasi penyandian di tempat lain, mis. Protokol HTTP menggunakan header Tipe-Konten untuk itu.
Salah satu pendekatan sederhana adalah untuk memeriksa apakah unicodefungsi builtin. Jika demikian, Anda menggunakan Python 2 dan string Anda akan menjadi string. Untuk memastikan semuanya dalam unicodesatu dapat dilakukan:
import builtins
i ='cats'if'unicode'in dir(builtins):# True in python 2, False in 3
i = unicode(i)
{UnicodeDecodeError} 'ascii' codec can't decode byte 0xc2
Jawaban:
Dalam Python 3, semua string adalah urutan karakter Unicode. Ada
bytes
tipe yang menyimpan byte mentah.Dalam Python 2, sebuah string dapat berupa tipe
str
atau tipeunicode
. Anda dapat mengetahui kode mana yang menggunakan sesuatu seperti ini:Ini tidak membedakan "Unicode atau ASCII"; itu hanya membedakan tipe Python. String Unicode dapat terdiri dari karakter murni dalam rentang ASCII, dan bytestring dapat berisi ASCII, Unicode yang dikodekan, atau bahkan data non-tekstual.
sumber
Bagaimana cara mengetahui apakah suatu objek adalah string unicode atau byte
Anda bisa menggunakan
type
atauisinstance
.Dengan Python 2:
Dalam Python 2,
str
hanya urutan byte. Python tidak tahu apa penyandiannya. Theunicode
jenis adalah cara yang lebih aman untuk menyimpan teks. Jika Anda ingin lebih memahami ini, saya sarankan http://farmdev.com/talks/unicode/ .Dengan Python 3:
Dalam Python 3,
str
seperti Python 2unicode
, dan digunakan untuk menyimpan teks. Apa yang disebutstr
dengan Python 2 disebutbytes
dengan Python 3.Bagaimana cara mengetahui apakah sebuah byte string valid atau 8 atau ascii
Anda bisa menelepon
decode
. Jika itu memunculkan eksepsi UnicodeDecodeError, itu tidak valid.sumber
unicode(s, "ascii")
sesuatustr(s, "ascii")
Dalam python 3.x semua string adalah urutan karakter Unicode. dan melakukan isinstance check untuk str (yang berarti string unicode secara default) sudah cukup.
Sehubungan dengan python 2.x, Kebanyakan orang tampaknya menggunakan pernyataan if yang memiliki dua pemeriksaan. satu untuk str dan satu untuk unicode.
Jika Anda ingin memeriksa apakah Anda memiliki objek 'string-like' semua dengan satu pernyataan, Anda dapat melakukan hal berikut:
sumber
isinstance(u"x",basestring)
kembaliTrue
.Unicode bukan pengodean - mengutip Kumar McMillan:
Telah membaca tentang McMillan's Unicode In Python, bicara Sepenuhnya Demystified dari PyCon 2008, itu menjelaskan banyak hal lebih baik daripada sebagian besar jawaban terkait pada Stack Overflow.
sumber
Jika kebutuhan kode Anda agar kompatibel dengan kedua Python 2 dan Python 3, Anda tidak bisa langsung menggunakan hal-hal seperti
isinstance(s,bytes)
atauisinstance(s,unicode)
tanpa membungkus mereka baik mencoba / kecuali atau tes versi python, karenabytes
tidak terdefinisi dengan Python 2 danunicode
tidak terdefinisi di Python 3 .Ada beberapa solusi buruk. Yang sangat jelek adalah membandingkan nama tipe, bukan membandingkan tipe itu sendiri. Ini sebuah contoh:
Solusi yang bisa dibilang sedikit kurang jelek adalah memeriksa nomor versi Python, misalnya:
Keduanya unpythonic, dan sebagian besar waktu mungkin ada cara yang lebih baik.
sumber
six
, dan uji terhadapsix.binary_type
dansix.text_type
menggunakan:
di dalam enam perpustakaan direpresentasikan sebagai:
sumber
if isinstance(obj, six.text_type)
. Tapi ya ini adalah jawaban yang benar.Perhatikan bahwa pada Python 3, tidak adil untuk mengatakan:
str
s adalah UTFx untuk x (mis. UTF8)str
Ini adalah Unicodestr
s adalah koleksi karakter Unicode yang dipesanstr
Jenis Python adalah (biasanya) urutan titik kode Unicode, beberapa di antaranya memetakan karakter.Bahkan di Python 3, tidak semudah menjawab pertanyaan ini seperti yang Anda bayangkan.
Cara yang jelas untuk menguji string yang kompatibel dengan ASCII adalah dengan mencoba penyandian:
Kesalahan membedakan kasus.
Di Python 3, bahkan ada beberapa string yang berisi poin kode Unicode yang tidak valid:
Metode yang sama untuk membedakan mereka digunakan.
sumber
Ini dapat membantu orang lain, saya memulai pengujian untuk tipe string dari variabel s, tetapi untuk aplikasi saya, lebih masuk akal untuk mengembalikan s sebagai utf-8. Proses memanggil return_utf, kemudian tahu apa yang ia hadapi dan dapat menangani string dengan tepat. Kode ini tidak asli, tetapi saya bermaksud untuk menjadi agnostik versi Python tanpa tes versi atau mengimpor enam. Berikan komentar dengan penyempurnaan kode contoh di bawah ini untuk membantu orang lain.
sumber
Anda dapat menggunakan Universal Encoding Detector , tetapi ketahuilah bahwa itu hanya akan memberi Anda tebakan terbaik, bukan pengkodean yang sebenarnya, karena tidak mungkin untuk mengetahui pengkodean string "abc" misalnya. Anda perlu mendapatkan informasi penyandian di tempat lain, mis. Protokol HTTP menggunakan header Tipe-Konten untuk itu.
sumber
Untuk kompatibilitas py2 / py3 cukup gunakan
import six if isinstance(obj, six.text_type)
sumber
Salah satu pendekatan sederhana adalah untuk memeriksa apakah
unicode
fungsi builtin. Jika demikian, Anda menggunakan Python 2 dan string Anda akan menjadi string. Untuk memastikan semuanya dalamunicode
satu dapat dilakukan:sumber