Yanıtlar:
Python 3'te, tüm dizeler Unicode karakter dizileridir. bytes
Ham bayt tutan bir tür vardır.
Python 2'de, bir dize türü str
veya türü olabilir unicode
. Hangi kodu kullanarak böyle bir şey söyleyebilirsiniz:
def whatisthis(s):
if isinstance(s, str):
print "ordinary string"
elif isinstance(s, unicode):
print "unicode string"
else:
print "not a string"
Bu "Unicode veya ASCII" yi ayırt etmez; sadece Python tiplerini ayırt eder. Bir Unicode dizesi yalnızca ASCII aralığındaki karakterlerden oluşabilir ve bir bytestring ASCII, kodlanmış Unicode ve hatta metinsel olmayan veriler içerebilir.
Sen kullanabilir type
ya isinstance
.
Python 2'de:
>>> type(u'abc') # Python 2 unicode string literal
<type 'unicode'>
>>> type('abc') # Python 2 byte string literal
<type 'str'>
Python 2'de str
sadece bir bayt dizisidir. Python kodlamasının ne olduğunu bilmiyor. unicode
Tip mağaza metne daha güvenli bir yoldur. Bunu daha fazla anlamak istiyorsanız, http://farmdev.com/talks/unicode/ adresini öneriyorum .
Python 3'te:
>>> type('abc') # Python 3 unicode string literal
<class 'str'>
>>> type(b'abc') # Python 3 byte string literal
<class 'bytes'>
Python 3'te str
Python 2'ye benzer unicode
ve metin depolamak için kullanılır. Ne denirdi str
Python 2'de denir bytes
Python 3'te.
Arayabilirsiniz decode
. UnicodeDecodeError istisnasını yükseltirse, geçerli değildi.
>>> 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)
unicode(s, "ascii")
ya da böyle
str(s, "ascii")
Python 3.x sürümünde tüm dizeler Unicode karakter dizileridir. ve str için isinstance kontrolünün (varsayılan olarak unicode string anlamına gelir) yapılması yeterli olacaktır.
isinstance(x, str)
Python 2.x ile ilgili olarak, çoğu insan iki kontrol içeren bir if ifadesi kullanıyor gibi görünüyor. biri str, diğeri unicode için.
Yine de tek bir deyimle 'dize benzeri' bir nesneniz olup olmadığını kontrol etmek istiyorsanız, aşağıdakileri yapabilirsiniz:
isinstance(x, basestring)
isinstance(u"x",basestring)
geri döner True
.
Unicode bir kodlama değildir - Kumar McMillan'a alıntı yapmak için:
ASCII, UTF-8 ve diğer bayt dizeleri "metin" ise ...
... o zaman Unicode "metin" dir;
metnin soyut biçimidir
McMillan'ın Unicode In Python'u okuyun, PyCon 2008'den Tamamen Demystified konuşması, Stack Overflow'daki ilgili cevapların çoğundan çok daha iyi şeyler açıklıyor.
Kod ihtiyaçları ile uyumlu olacak şekilde olursa hem Python 2 ve Python 3, doğrudan gibi şeyler kullanamaz isinstance(s,bytes)
veya isinstance(s,unicode)
çünkü haricinde veya bir piton sürüm test / ya denemede onları sarma olmadan bytes
Python 2 tanımlanmamış ve unicode
Python 3 tanımlanmamış .
Bazı çirkin çözümler var. Son derece çirkin olanı, türün kendisini karşılaştırmak yerine türün adını karşılaştırmaktır. İşte bir örnek:
# convert bytes (python 3) or unicode (python 2) to str
if 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)
Tartışmasız biraz daha az çirkin bir çözüm, Python sürüm numarasını kontrol etmektir, örneğin:
if sys.version_info >= (3,0,0):
# for Python 3
if isinstance(s, bytes):
s = s.decode('ascii') # or s = str(s)[2:-1]
else:
# for Python 2
if isinstance(s, unicode):
s = str(s)
Her ikisi de unpythonic ve çoğu zaman muhtemelen daha iyi bir yol var.
six
ve test etmek six.binary_type
vesix.text_type
kullanın:
import six
if isinstance(obj, six.text_type)
altı kütüphanenin içinde şu şekilde temsil edilir:
if PY3:
string_types = str,
else:
string_types = basestring,
if isinstance(obj, six.text_type)
. Ama evet bu doğru cevap imo.
Python 3'te aşağıdakilerden herhangi birini söylemek gerçekten adil değil:
str
s herhangi bir x için UTFx'tir (örneğin UTF8)
str
s Unicode
str
s, Unicode karakterlerin sıralı koleksiyonlarıdır
Python'un str
türü (normalde) bazıları karakterlerle eşlenen bir Unicode kod noktası dizisidir.
Python 3'te bile, bu soruyu hayal edebileceğiniz kadar basit değil.
ASCII uyumlu dizeleri test etmenin bariz bir yolu, denenmiş bir kodlamadır:
"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)
Hata, vakaları ayırt eder.
Python 3'te, geçersiz Unicode kod noktaları içeren bazı dizeler bile vardır:
"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
Bunları ayırt etmek için aynı yöntem kullanılır.
Bu başka birine yardımcı olabilir, değişken s dize türü için teste başladım, ancak benim uygulama için, sadece s utf-8 olarak dönmek daha mantıklı. Return_utf öğesini çağıran işlem, neyle uğraştığını bilir ve dizeyi uygun şekilde işleyebilir. Kod bozulmamış değil, ama bir sürüm testi veya altı alma olmadan Python sürüm agnostik olmasını niyetinde. Diğer kişilere yardımcı olmak için lütfen aşağıdaki örnek kodda iyileştirmeler yaparak yorum yapın.
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')
except TypeError:
try:
return str(s).encode('utf-8')
except AttributeError:
return s
except AttributeError:
return s
return s # assume it was already utf-8
Evrensel Kodlama Dedektörü kullanabilirsiniz , ancak gerçek kodlamayı değil, size en iyi tahminin verileceğini unutmayın, çünkü örneğin bir "abc" dizesinin kodlamasını bilmek imkansızdır. Başka bir yerde kodlama bilgisi almanız gerekir, örneğin HTTP protokolü bunun için Content-Type üstbilgisini kullanır.
Py2 / py3 uyumluluğu için
import six
if isinstance(obj, six.text_type)
Basit bir yaklaşım, unicode
yerleşik bir işlev olup olmadığını kontrol etmektir. Eğer öyleyse, Python 2'desiniz ve dizeniz bir dize olacaktır. Her şeyin unicode
yapılabileceğinden emin olmak için:
import builtins
i = 'cats'
if 'unicode' in dir(builtins): # True in python 2, False in 3
i = unicode(i)