如何检查string是unicode还是ascii?
在Python中我需要做什么来弄清楚哪一种编码?
在Python 3中,所有的string都是Unicode字符的序列。 有一个保存原始字节的bytes
types。
在Python 2中,一个string可能是str
或unicode
types。 你可以告诉哪个代码如下所示:
def whatisthis(s): if isinstance(s, str): print "ordinary string" elif isinstance(s, unicode): print "unicode string" else: print "not a string"
做就是了
type(s)
一个会说unicode
,另一个会说str
。
你可以使用isinstance
分别处理它们,例如
if isinstance(s, str): print 's is a string object' elif isinstance(s, unicode): print 's is a unicode object'
或者你的意思是你有一个str
,而你试图弄清楚它是否使用ASCII
或UTF-8
或其他编码?
在这种情况下,试试这个:
s.decode('ascii')
如果引发exception,string不是100%ASCII。
在python 3.x中,所有string都是Unicode字符的序列。 并且对str进行isinstance检查(意味着默认情况下使用unicodestring)就足够了。
isinstance(x, str)
关于Python 2.x,大多数人似乎使用了一个if语句,它有两个检查。 一个是str,一个是unicode。
如果你想检查是否有一个“string”的对象,所有的一个语句,但你可以做到以下几点:
isinstance(x, basestring)
Unicode不是一种编码 – 引用Kumar McMillan:
如果ASCII,UTF-8和其他字节string是“文本”…
那么Unicode就是“文本”。
它是文本的抽象forms
阅读McMillan的Unicode In Python,完全揭秘 PyCon 2008的话题,它比堆栈溢出的大多数相关答案解释得更好。
如果您的代码需要与Python 2和Python 3兼容,则不能直接使用isinstance(s,bytes)
或isinstance(s,unicode)
而不将其包装在try / except或python版本testing中,因为在Python 2中bytes
是未定义的, unicode
在Python 3中未定义。
有一些丑陋的解决方法。 一个非常丑陋的是比较types的名称 ,而不是比较types本身。 这是一个例子:
# 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)
一个可以说是稍微不太丑陋的解决方法是检查Python的版本号,例如:
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)
这些都是和谐的,大多数时候可能有更好的方法。
使用:
import six if isinstance(obj, six. text_type)
里面的六个库里面代表着:
if PY3: string_types = str, else: string_types = basestring,
请注意,在Python 3中,说任何一个都不太公平:
-
str
是任何x的UTFx(例如UTF8) -
str
是Unicode -
str
是Unicode字符的有序集合
Python的str
types(通常)是一系列的Unicode代码点,其中一些映射到字符。
即使在Python 3中,回答这个问题也不像你想像的那么简单。
testingASCII兼容string的一个显而易见的方法是尝试编码:
"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)
错误区分的情况。
在Python 3中,甚至有一些包含无效的Unicode代码点的string:
"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
使用相同的方法来区分它们。
您可以使用通用编码检测器 ,但请注意,它只会给你最好的猜测,而不是实际的编码,因为例如不可能知道string“abc”的编码。 您需要在别处获取编码信息,例如HTTP协议使用Content-Type标头。
这可能对别人有帮助,我开始testingvariabless的stringtypes,但是对于我的应用程序来说,仅仅以utf-8的forms返回s就更有意义了。 调用return_utf的进程知道它正在处理什么,并可以正确处理string。 该代码不是原始的,但我打算它是Python版本agnostic没有版本testing或导入六。 请对以下示例代码进行改进以帮助其他人。
def return_utf(s): if isinstance(s, str): return s.encode('utf-8') if isinstance(s, int): return str(s).encode('utf-8') if isinstance(s, float): return str(s).encode('utf-8') if isinstance(s, 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