GVKun编程网logo

普通的python字符串使用什么编码?(python字符串的编码规则)

17

在本文中,我们将带你了解普通的python字符串使用什么编码?在这篇文章中,我们将为您详细介绍普通的python字符串使用什么编码?的方方面面,并解答python字符串的编码规则常见的疑惑,同时我们还

在本文中,我们将带你了解普通的python字符串使用什么编码?在这篇文章中,我们将为您详细介绍普通的python字符串使用什么编码?的方方面面,并解答python字符串的编码规则常见的疑惑,同时我们还将给您一些技巧,以帮助您实现更有效的Python 2.x中的字符串使用哪种编码?、Python 普通str字符串 和 unicode 字符串 及字符串编码探测、转换、python---字符串使用方法、Python2.7 中文字符编码,使用Unicode时,选择什么编码格式?

本文目录一览:

普通的python字符串使用什么编码?(python字符串的编码规则)

普通的python字符串使用什么编码?(python字符串的编码规则)

我知道django在整个框架中使用unicode字符串,而不是普通的python字符串。普通的python字符串使用什么编码?他们为什么不使用unicode?

答案1

小编典典

从Python
3.0开始,默认情况下所有字符串都是unicode,还有bytes数据类型(Python文档)。

因此,python开发人员认为使用unicode是一个好主意,因为在向后兼容性方面,在python 2中并未普遍使用它。它还对性能有影响。

Python 2.x中的字符串使用哪种编码?

Python 2.x中的字符串使用哪种编码?

在python 2.x中用于编码字符串的默认编码是什么?我读过有两种可能的方法来声明一个字符串。

string = ''this is a string''unicode_string = u''this is a unicode string''

第二个字符串是Unicode。第一个字符串的编码是什么?

答案1

小编典典

按照Python的默认/隐式字符串编码和转换(简洁地引用其Py2部分,以最大程度地减少重复):

实际上,Python 2中有多个独立的“默认”字符串编码, 供其功能的不同部分使用。

  • 解析代码和字符串文字:

    • str 从文字中获取-将包含文件中的原始字节,不进行转码
    • unicode从文字中获取-文件中的字节以decode“ d”加上文件的“源编码”,默认为ascii
    • 随着unicode_literalsfuture,文件中的所有文字都被视为Unicode文字
    • 转码/类型转换:

    • str<->unicode类型转换和encode/不decode带参数完成sys.getdefaultencoding()

    • 这是ascii几乎总是,所以任何国家的字符将会导致UnicodeError
    • str只能是decode“d和unicode- encode” d。否则尝试将涉及隐式类型转换(具有上述结果)
    • I / O,包括printing:

    • unicode-如果已设置,则为encode‘d’ <file>.encoding,否则将隐式转换为str(具有上述结果)

    • str-将原始字节写入流,不进行任何代码转换。对于国家字符,终端将根据其语言环境设置显示不同的字形。

Python 普通str字符串 和 unicode 字符串 及字符串编码探测、转换

Python 普通str字符串 和 unicode 字符串 及字符串编码探测、转换

本文研究时的环境是CentOS release 6.4,内核版本2.6.32-358.el6.x86_64,python2.6.6

内容:关于字符串的两个魔术方法__str__() 、__unicode__() 两个函数str() 、unicode() 类型转换encode 、decode 和编码探测chardet、 cchardet

先看一下对象的两个魔术方法

第一个:object.__str__(self)

Called by the str() built-in function and by the print statement to compute the “informal” string representation of an object.The return value must be a string object.

内建函数str()print语句 调用,产生非正式的对对象的描述字符串。返回值必须是string对象(这里指的应该是bytes object字节对象)

第二个:object.__unicode__(self)

Called to implement unicode() built-in; should return a Unicode object. When this method is not defined,string conversion is attempted, and the result of string conversion is converted to Unicode using the system default encoding.

被内建函数unicode()调用;应当返回一个Unicode对象。当没有定义此方法时,将会尝试字符串转换,字符串转换的结果是:使用系统默认编码将其转换为Unicode string。

str() 和 unicode()

str(object='''')

Return a string containing a nicely printable representation of an object. For strings, this returns the string itself.If no argument is given, returns the empty string, ''''.

返回对传入对象的便于打印的描述的字符串(调用对象的__str__()方法)。对于字符串对象(字节对象)将会返回他本身。如果没有参数,将返回空字符串。

unicode(object='''')

unicode(object[, encoding[, errors]])

If no optional parameters are given, unicode() will mimic the behaviour of str() except that it returns Unicode strings instead of 8-bit strings. More precisely, if object is a Unicode string or subclass it will return that Unicode string without any additional decoding applied.

如果没有提供可选参数,unicode()将会模拟str()的行为,只是返回的是Unicode strings而不是8-bit strings。更准确的情况,如果传入的对象是Unicode string或他的子类,将不会进行任何译码操作,直接返回它本身。

For objects which provide a __unicode__() method, it will call this method without arguments to create a Unicode string. For all other objects, the 8-bit string version or representation is requested and then converted to a Unicode string using the codec for the default encoding in ''strict'' mode.

对于提供了__unicode__()方法的对象,将不带参数调用此方法。其他情况下传入的必须是8-bit字符串描述,而后用编码解码器用系统默认编码译码为Unicode string。

If encoding and/or errors are given, unicode() will decode the object which can either be an 8-bit string or a character buffer using the codec for encoding. The encoding parameter is a string giving the name of an encoding; if the encoding is not known, LookupError is raised. Error handling is done according toerrors; this specifies the treatment of characters which are invalid in the input encoding. If errors is''strict'' (the default), a ValueError is raised on errors, while a value of ''ignore'' causes errors to be silently ignored, and a value of ''replace'' causes the official Unicode replacement character, U+FFFD, to be used to replace input characters which cannot be decoded. See also the codecs module.

简单的说就是将传入的8-bit字串或缓冲区用指定的编码解码生成Unicode string,error参数用来指定无法解码时的处理方式。

小结:

str():调用对象的__str__()方法,产生8-bit string

unicode():调用对象的__unicode__()方法,返回Unicode string。如过对象没有__unicode__()方法就调用__str__()方法生成8-bit string(传入的如果就是8-bit string将省略这一步),然后对其用系统默认编码解码,生成Unicode string。

可见,我们自己做的类,最好还是提供__str__()和__unicode__()方法,对于写日志,debug等是很有用的。

注:查看python系统默认编码(上文中unicode()将会使用的默认值)

import sys
print sys.getdefaultencoding()

在交互模式设置字符编码

>>> reload(sys) # 这个很重要,否则报错
<module ''sys'' (built-in)>
>>> sys.setdefaultencoding(''utf8'')
>>> sys.getdefaultencoding()
''utf8''

 

普通string和Unicode string的区别

首先确认系统环境设置的是UTF-8:
echo $LANG
en_US.UTF-8

然后确认使用的终端调成utf-8编码否则有些实验会混乱。

1.普通string可以理解为我们平时理解的字符串,一个缓冲区里边放着字符串,内容可能是各种类型的编码。(我是把它当作C语言char型数组理解的)

>>> str_string = ''你好,字符编码''

str_string的内容可能是:

utf8:   ''\xe4\xbd\xa0\xe5\xa5\xbd\xef\xbc\x8c\xe7\xbc\x96\xe7\xa0\x81''

utf16:   ''\xff\xfe`O}Y\x0c\xff\x16\x7f\x01x''

utf32:   ''\xff\xfe\x00\x00`O\x00\x00}Y\x00\x00\x0c\xff\x00\x00\x16\x7f\x00\x00\x01x\x00\x00''

gb2312: ''\xc4\xe3\xba\xc3\xa3\xac\xb1\xe0\xc2\xeb''

2. unicode是一种对象,用unicode字符集保存字符串(内部存储的是UCS2或UCS4,更底层依据操作系统的环境,是用wchar_t、unsigned short或unsigned long。详情可在python文档中搜索Encodings and Unicode及Py_UNICODE,

 

>>> unicode_string = u''你好,字符编码''
>>> unicode_string
u''\u4f60\u4f1a\u597d\uff0c\u5b57\u7b26\u7f16\u7801''

下面这种情况(unicode应该是u''里边是\uxxxx的格式,但这个却是\x的),应该是系统编码与终端(本人用的Xshell)编码不一致造成,其实u''\xe4'' == u''\u00e4'',这样容易造成乱码,请避免这种环境。

>>> unicode_string = u''你好,字符编码''
>>> unicode_string
u''\xe4\xbd\xa0\xe5\xa5\xbd\xef\xbc\x8c\xe5\xad\x97\xe7\xac\xa6\xe7\xbc\x96\xe7\xa0\x81''

参考http://stackoverflow.com/questions/9845842/bytes-in-a-unicode-python-string

小结:

普通字符串(8-bit string,字节字符串):

是用挨着的一个一个8位的二进制位保存字符串,是有编码的区别的。

Unicode string:

是用UCS2(或UCS4编译时决定)保存字符串的对象,是没有编码区别,用它可以生成各种编码的普通字符串。

encode和decode的使用

上边两种字符串的区别弄明白了这两个函数就好理解了

encode是编码,decode是解码。

Unicode字符串要变成普通字符串就要用某种编码去“编码”(encode)。

普通字符串需要知道它本身是什么编码的,用此编码来“解码”(decode)才能生成Unicode字符串对象。

所以:

encode的使用

>>> a = u''你好,世界!''
>>> a
u''\u4f60\u597d\uff0c\u4e16\u754c\uff01''
>>> a.encode(''utf8'')
''\xe4\xbd\xa0\xe5\xa5\xbd\xef\xbc\x8c\xe4\xb8\x96\xe7\x95\x8c\xef\xbc\x81''
>>> a.encode(''utf16'')
''\xff\xfe`O}Y\x0c\xff\x16NLu\x01\xff''
>>> a.encode(''gb2312'')
''\xc4\xe3\xba\xc3\xa3\xac\xca\xc0\xbd\xe7\xa3\xa1''
>>> a.encode(''ascii'') # 因为ascii字符集无法表示中文,所以会报错,字符串是u''Hello,World!''就行了
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: ''ascii'' codec can''t encode characters in position 0-5: ordinal not in range(128)
>>>

decode的使用

>>> b = a.encode(''utf8'')#先用a生成某中编码的普通字符串,然后进行decode,注意编码必须对应!
>>> b.decode(''utf8'')
u''\u4f60\u597d\uff0c\u4e16\u754c\uff01''
>>> b = a.encode(''utf16'')
>>> b.decode(''utf16'')
u''\u4f60\u597d\uff0c\u4e16\u754c\uff01''
>>> b = a.encode(''gb2312'')
>>> b.decode(''gb2312'')
u''\u4f60\u597d\uff0c\u4e16\u754c\uff01''
>>> b = a.encode(''utf8'')
>>> b.decode(''gb2312'')#编码不对应的情况,b是utf8编码的字符串,用gb2312是不能解码的。
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: ''gb2312'' codec can''t decode bytes in position 2-3: illegal multibyte sequence
>>> b.decode(''gb2312'',''ignore'')#这时候第二个参数出场了,可以设置忽略或者用问号替换,防止抛出异常
u''\u6d63\u30bd\u951b''
>>> print b.decode(''gb2312'',''ignore'')
浣ソ锛
>>> b.decode(''gb2312'',''replace'')
u''\u6d63\ufffd\u30bd\u951b\ufffd\ufffd\ufffd\ufffd\ufffd''
>>> print b.decode(''gb2312'',''replace'')
浣�ソ锛�����
>>>

来个混合使用的:-)

>>> a = u''你好,世界!''
>>> a
u''\u4f60\u597d\uff0c\u4e16\u754c\uff01''
>>> a.encode(''utf8'').decode(''utf8'')
u''\u4f60\u597d\uff0c\u4e16\u754c\uff01''
>>> a.encode(''utf8'').decode(''utf8'').encode(''gb2312'')
''\xc4\xe3\xba\xc3\xa3\xac\xca\xc0\xbd\xe7\xa3\xa1''
>>> a.encode(''utf8'').decode(''utf8'').encode(''gb2312'').decode(''gb2312'')
u''\u4f60\u597d\uff0c\u4e16\u754c\uff01''
>>> a.encode(''utf8'').decode(''utf8'').encode(''gb2312'').decode(''gb2312'').encode(''utf16'')
''\xff\xfe`O}Y\x0c\xff\x16NLu\x01\xff''
>>> a.encode(''utf8'').decode(''utf8'').encode(''gb2312'').decode(''gb2312'').encode(''utf16'').decode(''utf16'')u''\u4f60\u597d\uff0c\u4e16\u754c\uff01''

 

python普通字符串编码检测

普通字符串有编码的分别,我们经常遇到通过网络或打开某个文件读取字符串的情况,而如果对端不是我们自己的程序,用的什么编码还真不好说,这就涉及到字符串编码检测了。

提前声明:

1.理论上是无法100%检测出是什么编码的,因为各种编码间存在冲突,同一个编码可能不同的字符集里都出现了,但是代表不同的字符,这里只能说检测字符串最可能是什么编码。(比如虽然你是用utf8编码的‘abc’,但是会被探测为ascii,因为ascii表示a、b、c的编码和utf8一样,这是utf8对ascii的兼容特性,其他各种编码很多也有这种兼容ascii的设计,这就是全屏乱码,字母数字下划线不会乱的原因所在,因为用任何编码解码都能正确显示abc123)

2.只能探测出“测码库”支持的编码,不支持的编码就无能为力了。(设想你自己制定的私有编码,别人怎么能检测出?)

3.被探测的样本字符串字符数越多越准确,太少了不行,两三个汉字的gb2312字符串是不能正确检测出的。

言归正传,咱们开始解码!!

先去pypi下载检测字符编码的库chardet或cchardet(文档说它更快,但是依赖另外的一个库)

https://pypi.python.org/pypi?%3Aaction=search&term=chardet&submit=search

 来自chardet文档的例子:

The easiest way to use the Universal Encoding Detector library is with the detect function.

>>> import urllib
>>> rawdata = urllib.urlopen(''http://yahoo.co.jp/'').read()
>>> import chardet
>>> chardet.detect(rawdata)
{''encoding'': ''EUC-JP'', ''confidence'': 0.99}

 

 

更高级的例子:

If you’re dealing with a large amount of text, you can call the Universal Encoding Detector library incrementally, and it will stop as soon as it is confident enough to report its results.

import urllib
from chardet.universaldetector import UniversalDetector

usock = urllib.urlopen(''http://yahoo.co.jp/'')
detector = UniversalDetector()
for line in usock.readlines():
    detector.feed(line)
    if detector.done: break
detector.close()
usock.close()
print detector.result
{''encoding'': ''EUC-JP'', ''confidence'': 0.99}

 

 

还有一个:

If you want to detect the encoding of multiple texts (such as separate files)

import glob
from chardet.universaldetector import UniversalDetector

detector = UniversalDetector()
for filename in glob.glob(''*.xml''):
    print filename.ljust(60),
    detector.reset()
    for line in file(filename, ''rb''):
        detector.feed(line)
        if detector.done: break
    detector.close()
    print detector.result

 

 

附:一篇比较好的关于python编码的文章,英文的但很易懂。

Making Sense of Python Unicode

python---字符串使用方法

python---字符串使用方法

capitalize() 把字符串的第一个字符改为大写
casefold() 把整个字符串的所有字符改为小写
center(width) 将字符串居中,并使用空格填充至长度 width 的新字符串
count(sub[, start[, end]]) 返回 sub 在字符串里边出现的次数,start 和 end 参数表示范围,可选。
encode(encoding=''utf-8'', errors=''strict'') 以 encoding 指定的编码格式对字符串进行编码。
endswith(sub[, start[, end]]) 检查字符串是否以 sub 子字符串结束,如果是返回 True,否则返回 False。start 和 end 参数表示范围,可选。
expandtabs([tabsize=8]) 把字符串中的 tab 符号(\t)转换为空格,如不指定参数,默认的空格数是 tabsize=8。
find(sub[, start[, end]]) 检测 sub 是否包含在字符串中,如果有则返回索引值,否则返回 -1,start 和 end 参数表示范围,可选。
index(sub[, start[, end]]) 跟 find 方法一样,不过如果 sub 不在 string 中会产生一个异常。
isalnum() 如果字符串至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False。
isalpha() 如果字符串至少有一个字符并且所有字符都是字母则返回 True,否则返回 False。
isdecimal() 如果字符串只包含十进制数字则返回 True,否则返回 False。
isdigit() 如果字符串只包含数字则返回 True,否则返回 False。
islower() 如果字符串中至少包含一个区分大小写的字符,并且这些字符都是小写,则返回 True,否则返回 False。
isnumeric() 如果字符串中只包含数字字符,则返回 True,否则返回 False。
isspace() 如果字符串中只包含空格,则返回 True,否则返回 False。
istitle() 如果字符串是标题化(所有的单词都是以大写开始,其余字母均小写),则返回 True,否则返回 False。
isupper() 如果字符串中至少包含一个区分大小写的字符,并且这些字符都是大写,则返回 True,否则返回 False。
join(sub) 以字符串作为分隔符,插入到 sub 中所有的字符之间。
ljust(width) 返回一个左对齐的字符串,并使用空格填充至长度为 width 的新字符串。
lower() 转换字符串中所有大写字符为小写。
lstrip() 去掉字符串左边的所有空格
partition(sub) 找到子字符串 sub,把字符串分成一个 3 元组 (pre_sub, sub, fol_sub),如果字符串中不包含 sub 则返回 (''原字符串'', '''', '''')
replace(old, new[, count]) 把字符串中的 old 子字符串替换成 new 子字符串,如果 count 指定,则替换不超过 count 次。
rfind(sub[, start[, end]]) 类似于 find() 方法,不过是从右边开始查找。
rindex(sub[, start[, end]]) 类似于 index() 方法,不过是从右边开始。
rjust(width) 返回一个右对齐的字符串,并使用空格填充至长度为 width 的新字符串。
rpartition(sub) 类似于 partition() 方法,不过是从右边开始查找。
rstrip() 删除字符串末尾的空格。
split(sep=None, maxsplit=-1) 不带参数默认是以空格为分隔符切片字符串,如果 maxsplit 参数有设置,则仅分隔 maxsplit 个子字符串,返回切片后的子字符串拼接的列表。
splitlines(([keepends])) 在输出结果里是否去掉换行符,默认为 False,不包含换行符;如果为 True,则保留换行符。。
startswith(prefix[, start[, end]]) 检查字符串是否以 prefix 开头,是则返回 True,否则返回 False。start 和 end 参数可以指定范围检查,可选。
strip([chars]) 删除字符串前边和后边所有的空格,chars 参数可以定制删除的字符,可选。
swapcase() 翻转字符串中的大小写。
title() 返回标题化(所有的单词都是以大写开始,其余字母均小写)的字符串。
translate(table) 根据 table 的规则(可以由 str.maketrans(''a'', ''b'') 定制)转换字符串中的字符。
upper() 转换字符串中的所有小写字符为大写。
zfill(width) 返回长度为 width 的字符串,原字符串右对齐,前边用 0 填充。

Python2.7 中文字符编码,使用Unicode时,选择什么编码格式?

Python2.7 中文字符编码,使用Unicode时,选择什么编码格式?

回复内容:

关于编码和乱码的问题,我简单讲一下。

通常问这类问题的人是混淆了若干个不同的概念,并且他们自己也没有意识到自己混淆了这些概念的。

  1. 终端显示字符的编码(windows下终端是cmd,linux下是各种terminal,远程登录是putty或者xshell)
  2. shell环境的编码。比如中文版windows用的是gbk(向下兼容gb2312),大多数linux发行版使用的是utf-8(LANG=zh_CN.UTF-8)。
  3. 文本文件的编码。这个通常取决于你的编辑器,而且有的编辑器支持多种编码的话,你可以在文本开头位置指定编辑器使用特定编码。比如# -*- coding: utf8 -*-,vim看到这行会默认将这个脚本认定为utf-8兼容编码格式。
  4. 应用程序的内部编码。一个字符串,作为数据只是一个字节数组,但是作为字符的数组,就有一个解析方式。java和python的内部字符编码是utf-16,python和java都支持用不同的编码来对字节数组进行decode来得到字符数组。

拿题主的问题来解释一下。

我在ubuntu kylin中文环境下默认terminal中做了同样的实验,但是结果和题主恰好相反:
Python2.7 中文字符编码,使用Unicode时,选择什么编码格式?
Python2.7 中文字符编码,使用Unicode时,选择什么编码格式?

看见没有?

题主和我都没有说谎,这是为什么呢?
因为
unicode("汉字","gb2312")
登录后复制
我觉得关键是区分“字节”和“字符”的概念,还要知道一点点字体的常识。

“字符”可以看成是一个抽象概念,如当楼主说“汉字”,其实他意思是表达的是表示这么一个概念的两个字符。

当字符在计算机中表示的时候,需要编码成二进制(字节),于是就出现了不同的编码方式,如 GBK, UTF-8 等。如 Kenneth 展示的,“汉字”这两个字符在 GBK 中编码为 0xBABAD7D6,而在 UTF-8 中编码为 0xE6B189E5AD97。

最终显示时,则还要根据所使用的字体,把抽象的字符转化成具象的图像。

所以,楼主的第一个问题在于虽然你看到的是“汉字”的图像,但其在该脚本的源文件中的字节编码可能是任何一种——在 Windows 下是 GBK 或 GB18030 等。于是 python 看到的是一串 GBK / GB18030 编码的字节,而你试图告诉 python 这是 UTF-8 编码的,那自然报错了。

第二个问题,对 SQL Server 不熟,不过看起来原因是当你把从数据库读出的数据(字节形式,可能是 GBK 等非 Unicode 编码)放入 unit 这个变量的时候,程序错把非 Unicode 编码的字节当成 Unicode 编码解释了。那么排查思路应该是搞清楚数据在读出时是什么编码(这可能跟数据存入时的编码相关,也可能跟数据库配置有关),以及存入 unit 时程序做了哪些转换。

今天关于普通的python字符串使用什么编码?python字符串的编码规则的介绍到此结束,谢谢您的阅读,有关Python 2.x中的字符串使用哪种编码?、Python 普通str字符串 和 unicode 字符串 及字符串编码探测、转换、python---字符串使用方法、Python2.7 中文字符编码,使用Unicode时,选择什么编码格式?等更多相关知识的信息可以在本站进行查询。

本文标签: