Python字符编码详解!

笔记-python字符串编码 (补充一个问题,在python3.x中,只要把unicode编码,字符串就会变成了bytes格式,也不直接打印成gbk的字符,我觉得就是想通过这样的方式明确的告诉你,想在python3.x中看字符串,必须是unicode,其他编码一律是bytes格式)。无论以什么编码存储的数据,只要我们的软件把数据从硬盘上读到内存,转成unicode来显示即可,由于所有的系统、编程语言都默认支持unicode,所有我们的gbk编码软件放在美国电脑上,加载到内存里面,变成了unicode,中文就可正常展示。 阅读详情
AI摘要

本文介绍了常用字符编码如ASCII、MBCS、Unicode的特点,阐述Python2.x中的编码问题,包括str和unicode区别、字符编码声明、读写文件及相关方法。同时给出建议,如统一编码声明、多用unicode、用codecs.open()替代open(),避免用MBCS/DBCS和UTF - 16。

本文简单介绍了各种常用的字符编码的特点,并介绍了在python2.x中如何与编码问题作战 :)
请注意本文关于Python的内容仅适用于2.x,3.x中str和unicode有翻天覆地的变化,请查阅其他相关文档。
尊重作者的劳动,转载请注明作者及原文地址 >.<

包含编程籽料、学习路线图、源代码、软件安装包等!【点击领取 100%免费!】

1. 字符编码简介

1.1. ASCII

ASCII(American Standard Code for Information Interchange),是一种单字节的编码。计算机世界里一开始只有英文,而单字节可以表示256个不同的字符,可以表示所有的英文字符和许多的控制符号。不过ASCII只用到了其中的一半(\x80以下),这也是MBCS得以实现的基础。

1.2. MBCS

然而计算机世界里很快就有了其他语言,单字节的ASCII已无法满足需求。后来每个语言就制定了一套自己的编码,由于单字节能表示的字符太少,而且同时也需要与ASCII编码保持兼容,所以这些编码纷纷使用了多字节来表示字符,如GBxxx、BIGxxx等等,他们的规则是,如果第一个字节是\x80以下,则仍然表示ASCII字符;而如果是\x80以上,则跟下一个字节一起(共两个字节)表示一个字符,然后跳过下一个字节,继续往下判断。

这里,IBM发明了一个叫Code Page的概念,将这些编码都收入囊中并分配页码,GBK是第936页,也就是CP936。所以,也可以使用CP936表示GBK。

MBCS(Multi-Byte Character Set)是这些编码的统称。目前为止大家都是用了双字节,所以有时候也叫做DBCS(Double-Byte Character Set)。必须明确的是,MBCS并不是某一种特定的编码,Windows里根据你设定的区域不同,MBCS指代不同的编码,而Linux里无法使用MBCS作为编码。在Windows中你看不到MBCS这几个字符,因为微软为了更加洋气,使用了ANSI来吓唬人,记事本的另存为对话框里编码ANSI就是MBCS。同时,在简体中文Windows默认的区域设定里,指代GBK。

1.3. Unicode

后来,有人开始觉得太多编码导致世界变得过于复杂了,让人脑袋疼,于是大家坐在一起拍脑袋想出来一个方法:所有语言的字符都用同一种字符集来表示,这就是Unicode。

最初的Unicode标准UCS-2使用两个字节表示一个字符,所以你常常可以听到Unicode使用两个字节表示一个字符的说法。但过了不久有人觉得256*256太少了,还是不够用,于是出现了UCS-4标准,它使用4个字节表示一个字符,不过我们用的最多的仍然是UCS-2。

UCS(Unicode Character Set)还仅仅是字符对应码位的一张表而已,比如"汉"这个字的码位是6C49。字符具体如何传输和储存则是由UTF(UCS Transformation Format)来负责。

一开始这事很简单,直接使用UCS的码位来保存,这就是UTF-16,比如,"汉"直接使用\x6C\x49保存(UTF-16-BE),或是倒过来使用\x49\x6C保存(UTF-16-LE)。但用着用着美国人觉得自己吃了大亏,以前英文字母只需要一个字节就能保存了,现在大锅饭一吃变成了两个字节,空间消耗大了一倍……于是UTF-8横空出世。

UTF-8是一种很别扭的编码,具体表现在他是变长的,并且兼容ASCII,ASCII字符使用1字节表示。然而这里省了的必定是从别的地方抠出来的,你肯定也听说过UTF-8里中文字符使用3个字节来保存吧?4个字节保存的字符更是在泪奔……(具体UCS-2是怎么变成UTF-8的请自行搜索)

另外值得一提的是BOM(Byte Order Mark)。我们在储存文件时,文件使用的编码并没有保存,打开时则需要我们记住原先保存时使用的编码并使用这个编码打开,这样一来就产生了许多麻烦。(你可能想说记事本打开文件时并没有让选编码?不妨先打开记事本再使用文件 -> 打开看看)而UTF则引入了BOM来表示自身编码,如果一开始读入的几个字节是其中之一,则代表接下来要读取的文字使用的编码是相应的编码:

BOM_UTF8 ‘\xef\xbb\xbf’
BOM_UTF16_LE ‘\xff\xfe’
BOM_UTF16_BE ‘\xfe\xff’

并不是所有的编辑器都会写入BOM,但即使没有BOM,Unicode还是可以读取的,只是像MBCS的编码一样,需要另行指定具体的编码,否则解码将会失败。

你可能听说过UTF-8不需要BOM,这种说法是不对的,只是绝大多数编辑器在没有BOM时都是以UTF-8作为默认编码读取。即使是保存时默认使用ANSI(MBCS)的记事本,在读取文件时也是先使用UTF-8测试编码,如果可以成功解码,则使用UTF-8解码。记事本这个别扭的做法造成了一个BUG:如果你新建文本文件并输入"姹塧"然后使用ANSI(MBCS)保存,再打开就会变成"汉a",你不妨试试 :)

2. Python2.x中的编码问题

2.1. str和unicode

str和unicode都是basestring的子类。严格意义上说,str其实是字节串,它是unicode经过编码后的字节组成的序列。对UTF-8编码的str’汉’使用len()函数时,结果是3,因为实际上,UTF-8编码的’汉’ == ‘\xE6\xB1\x89’。

unicode才是真正意义上的字符串,对字节串str使用正确的字符编码进行解码后获得,并且len(u’汉’) == 1。

再来看看encode()和decode()两个basestring的实例方法,理解了str和unicode的区别后,这两个方法就不会再混淆了:

\# coding: UTF-8

u = u'汉'
print repr(u) # u'\\u6c49'
s = u.encode('UTF-8')
print repr(s) # '\\xe6\\xb1\\x89'
u2 = s.decode('UTF-8')
print repr(u2) # u'\\u6c49'

# 对unicode进行解码是错误的
# s2 = u.decode('UTF-8')
# 同样,对str进行编码也是错误的
# u2 = s.encode('UTF-8')

需要注意的是,虽然对str调用encode()方法是错误的,但实际上Python不会抛出异常,而是返回另外一个相同内容但不同id的str;对unicode调用decode()方法也是这样。很不理解为什么不把encode()和decode()分别放在unicode和str中而是都放在basestring中,但既然已经这样了,我们就小心避免犯错吧。

2.2. 字符编码声明

源代码文件中,如果有用到非ASCII字符,则需要在文件头部进行字符编码的声明,如下:

#-\*- coding: UTF-8 -\*-

实际上Python只检查#、coding和编码字符串,其他的字符都是为了美观加上的。另外,Python中可用的字符编码有很多,并且还有许多别名,还不区分大小写,比如UTF-8可以写成u8。参见http://docs.python.org/library/codecs.html#standard-encodings。

另外需要注意的是声明的编码必须与文件实际保存时用的编码一致,否则很大几率会出现代码解析异常。现在的IDE一般会自动处理这种情况,改变声明后同时换成声明的编码保存,但文本编辑器控们需要小心 :)

2.3. 读写文件

内置的open()方法打开文件时,read()读取的是str,读取后需要使用正确的编码格式进行decode()。write()写入时,如果参数是unicode,则需要使用你希望写入的编码进行encode(),如果是其他编码格式的str,则需要先用该str的编码进行decode(),转成unicode后再使用写入的编码进行encode()。如果直接将unicode作为参数传入write()方法,Python将先使用源代码文件声明的字符编码进行编码然后写入。

\# coding: UTF-8

f = open('test.txt')
s = f.read()
f.close()
print type(s) # <type 'str'>
# 已知是GBK编码,解码成unicode
u = s.decode('GBK')

f = open('test.txt', 'w')
# 编码成UTF-8编码的str
s = u.encode('UTF-8')
f.write(s)
f.close()

另外,模块codecs提供了一个open()方法,可以指定一个编码打开文件,使用这个方法打开的文件读取返回的将是unicode。写入时,如果参数是unicode,则使用open()时指定的编码进行编码后写入;如果是str,则先根据源代码文件声明的字符编码,解码成unicode后再进行前述操作。相对内置的open()来说,这个方法比较不容易在编码上出现问题。

\# coding: GBK

import codecs

f = codecs.open('test.txt', encoding='UTF-8')
u = f.read()
f.close()
print type(u) # <type 'unicode'>

f = codecs.open('test.txt', 'a', encoding='UTF-8')
# 写入unicode
f.write(u)

# 写入str,自动进行解码编码操作
# GBK编码的str
s = '汉'
print repr(s) # '\\xba\\xba'
# 这里会先将GBK编码的str解码为unicode再编码为UTF-8写入
f.write(s) 
f.close()

2.4. 与编码相关的方法

sys/locale模块中提供了一些获取当前环境下的默认编码的方法。

\# coding:gbk

import sys
import locale

def p(f):
    print '%s.%s(): %s' % (f.\_\_module\_\_, f.\_\_name\_\_, f())

# 返回当前系统所使用的默认字符编码
p(sys.getdefaultencoding)

# 返回用于转换Unicode文件名至系统文件名所使用的编码
p(sys.getfilesystemencoding)

# 获取默认的区域设置并返回元祖(语言, 编码)
p(locale.getdefaultlocale)

# 返回用户设定的文本数据编码
# 文档提到this function only returns a guess
p(locale.getpreferredencoding)

# \\xba\\xba是'汉'的GBK编码
# mbcs是不推荐使用的编码,这里仅作测试表明为什么不应该用
print r"'\\xba\\xba'.decode('mbcs'):", repr('\\xba\\xba'.decode('mbcs'))

#在笔者的Windows上的结果(区域设置为中文(简体, 中国))
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh\_CN', 'cp936')
#locale.getpreferredencoding(): cp936
#'\\xba\\xba'.decode('mbcs'): u'\\u6c49'

3.一些建议

3.1. 使用字符编码声明,并且同一工程中的所有源代码文件使用相同的字符编码声明。

这点是一定要做到的。

3.2. 抛弃str,全部使用unicode。

按引号前先按一下u最初做起来确实很不习惯而且经常会忘记再跑回去补,但如果这么做可以减少90%的编码问题。如果编码困扰不严重,可以不参考此条。

3.3. 使用codecs.open()替代内置的open()。

如果编码困扰不严重,可以不参考此条。

3.4. 绝对需要避免使用的字符编码:MBCS/DBCS和UTF-16。

这里说的MBCS不是指GBK什么的都不能用,而是不要使用Python里名为’MBCS’的编码,除非程序完全不移植。

Python中编码’MBCS’与’DBCS’是同义词,指当前Windows环境中MBCS指代的编码。Linux的Python实现中没有这种编码,所以一旦移植到Linux一定会出现异常!另外,只要设定的Windows系统区域不同,MBCS指代的编码也是不一样的。分别设定不同的区域运行2.4小节中的代码的结果:

#中文(简体, 中国)
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh\_CN', 'cp936')
#locale.getpreferredencoding(): cp936
#'\\xba\\xba'.decode('mbcs'): u'\\u6c49'

#英语(美国)
#sys.getdefaultencoding(): UTF-8
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh\_CN', 'cp1252')
#locale.getpreferredencoding(): cp1252
#'\\xba\\xba'.decode('mbcs'): u'\\xba\\xba'

#德语(德国)
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh\_CN', 'cp1252')
#locale.getpreferredencoding(): cp1252
#'\\xba\\xba'.decode('mbcs'): u'\\xba\\xba'

#日语(日本)
#sys.getdefaultencoding(): gbk
#sys.getfilesystemencoding(): mbcs
#locale.getdefaultlocale(): ('zh\_CN', 'cp932')
#locale.getpreferredencoding(): cp932
#'\\xba\\xba'.decode('mbcs'): u'\\uff7a\\uff7a'

可见,更改区域后,使用mbcs解码得到了不正确的结果,所以,当我们需要使用’GBK’时,应该直接写’GBK’,不要写成’MBCS’。

UTF-16同理,虽然绝大多数操作系统中’UTF-16’是’UTF-16-LE’的同义词,但直接写’UTF-16-LE’只是多写3个字符而已,而万一某个操作系统中’UTF-16’变成了’UTF-16-BE’的同义词,就会有错误的结果。实际上,UTF-16用的相当少,但用到的时候还是需要注意。

最后:关于Python技术储备
学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!
包括:Python激活码+安装包、Python web开发,Python爬虫,Python数据分析,人工智能、自动化办公等学习教程。带你从零基础系统性的学好Python!

在这里插入图片描述

Python字符编码详解 在Python中,可以使用字符串的encode()方法将字符串转换为字节序列,并使用字节序列的decode()方法将字节序列转换回字符串。在Python中,字符编码是一个重要的概念,它涉及到如何将字符转换为字节序列以及如何将字节序列转换回字符。在上面的示例中,我们将字符串使用utf-8编码转换为字节序列。在上面的示例中,我们分别使用UTF-8、UTF-16和GB2312编码对字符串进行了编码操作,并将其解码回字符串。要将字节序列转换回字符串,可以使用字节序列的decode()方法,并指定相应的字符编码。 阅读详情

相关推荐

Python文件处理中的字符编码及字符集

UTF-8字符集是基于Unicode编码实现的兼容ASCII编码的变长字符编码,它可以表示全球所有语言的字符。这样可以确保文件读写时的字符编码和字符集与文件本身的编码和字符集一致,避免出现乱码等问题。UTF-8编码是一种变长编码,它可以使用1至4个字节来表示一个字符,可以表示Unicode中所有的字符。Python文件处理中的字符编码和字符集是非常重要的概念,它们会直接影响到文件的读写和处理。在进行文件处理时,应该尽可能地选择与文件本身一致的字符编码和字符集,以确保文件的正确性。

持续更新 907

Python之ASCII码

python之ASCII码

qq_43146264的博客 2万+

新手必看!BUUCTF-PWN题实战:从零搭建Kali环境到成功RIP栈溢出

本文为CTF二进制安全新手提供了一份详实的BUUCTF-PWN入门指南。内容涵盖从零搭建Kali Linux环境、安装配置pwntools等核心工具,到深入浅出地讲解栈溢出原理与汇编基础,并手把手带领读者完成一道名为“rip”的经典栈溢出题目实战,成功利用漏洞获取系统权限。

t8u9v0w1x的博客 504

Python 中的 ascii() 函数详解

ascii()函数是处理包含非 ASCII 字符的字符串时非常有用的工具。通过将非 ASCII 字符转换为其对应的 Unicode 转义序列,可以更好地处理或显示这些字符串,提高程序的可读性和可维护性。在调试、日志记录或处理特殊字符时,使用ascii()函数可以帮助更轻松地处理字符串,并避免出现意外错误或异常。更多Python学习内容:ipengtao.com如果想要系统学习Python、Python问题咨询,或者考虑做一些工作以外的副业,都可以扫描二维码添加微信,围观朋友圈一起交流学习。

GitHub_miao的博客 4273

MobilenetV1、V2、V3系列详解

Mobilenet系列模型作为当前主流的端侧轻量级模型被广泛应用,很多算法都会使用其作为backbone提取特征,这一章对Mobilenet系列模型V1,V2,V3做一个总结。

turned的博客 1万+

基于STM32的简易电压、频率、占空比测量仪

任务详解:我们需要实现三个功能: 第一个是测频率的功能,输入信号为频率为1kHz~10kHz的三种波形(方波、三角波、正弦波),这也是我们最常见的三种波形。幅度是不需要测量的,所以先不关心幅度。 第二个是电压报警功能,当输入信号的幅度超过15V时,我们需要报警(这里我用了一个红色LED当报警器,有条件的还可以加个蜂鸣器)并且把此时的信号幅度显示在OLED屏幕上。 第三个是通信方式的要求,需要有串口通信功能。 第四个是计算占空比的任务,这个任务的输入是幅度为1V~10V、频率为20Hz ~1kHz的方波,需要

weixin_43469377的博客 7251

python——字符编码

1、如何解决乱码的情况 ```python #文件当初以什么标准编码,打开的时候就以什么标准解码 ``` > 2、python解释器版本不同带来的编码差异 * 由于Python2...实例如下: ```python s = '我要坚持学python!' #编码 res = s.encode('utf8') print(res,type(res))

chenchen5152的博客 2253

项目实训(四)——SAM模型的学习与部署

这里的show_mask就是我们用mask的prompt进行分割,show_points就是我们用points进行分割,show_box就是通过box进行分割,这是SAM的三种prompt的方式。总的来说,Meta AI 的 Segment Anything 模型为我们提供了一种全新的物体识别和分割方式,其强大的泛化能力和广泛的应用前景将极大地推动计算机视觉领域的发展。这里有vit_h、vit_b、vit_l三种权重模型,这里可以根据自己的需要下载相应的权重模型。我们是下载的vit_h权重模型。

yyyyyyyx_的博客 1421

Python 字符编码

在python 2中默认编码是 ASCII,而在python 3中默认编码是 unicode。 unicode 分为utf-32 (占4个字节),utf-16(占两个字节),utf-8(占1-4个字节),所以utf-16 是最常用的unicode版本,但是在文件里存的还是utf-8,因为utf8省空间。 在python 3,encode编码的同时会把string变成bytes类型,decode解码的同时会把bytes类型变成string类型。

IForFree 2922

纳米尺度仿真软件:GROMACS_(3).分子动力学模拟原理

分子动力学(MD)模拟是一种强大的计算方法,通过数值积分牛顿运动方程,追踪粒子在时间上的位置和速度变化,提供关于体系动力学行为的详细信息。选择合适的力场、设置初始条件、应用边界条件、控制温度和压力、选择合适的时间步长、计算能量和力,是 MD 模拟的关键步骤。通过这些步骤,可以对各种化学、生物和材料体系进行模拟和分析,揭示其结构、动力学和热力学性质。高级应用如反应路径模拟和蛋白质折叠研究,进一步扩展了 MD 模拟的应用范围。

kkchenjj的博客 1100

把浮点数这件小事讲清楚:ABAP 7.51 里 Open SQL 与 ABAP CDS 的 FLTP 新玩法与避坑指南

ABAP浮点数计算的风险与应对 摘要:ABAP项目中的浮点数(FLTP)在跨平台计算时存在误差风险,同一逻辑在不同数据库平台可能产生细微差异。ABAP 7.51新增了两项关键能力:1)Open SQL和ABAP CDS中可为AVG函数指定结果类型,避免默认返回FLTP;2)ABAP CDS提供FLTP_TO_DEC转换函数。但需注意这些转换仍可能存在平台相关差异,且FLTP_TO_DEC会截断而非四舍五入小数位。开发者在涉及金额、数量等关键业务计算时,应明确数值语义并设计容错机制。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 214

python可以处理任何字符编码文本对吗_Python字符编码详解

知识储备三大核心硬件#所有软件都是运行硬件之上的,与运行软件相关的三大核心硬件为cpu、内存、硬盘,我们需要明确三点#1、软件运行前,软件的代码及其相关数据都是存放于硬盘中的#2、任何软件的启动都是将数据从硬盘中读入内存,然后cpu从内存中取出指令并执行#3、软件运行过程中产生的数据最先都是存放于内存中的,若想永久保存软件产生的数据,则需要将数据由内存写入硬盘文本编辑器读取文件内容的流程#阶段1、...

weixin_39732866的博客 658

SAP成本核算的核心逻辑

SAP成本核算采用"计划-归集-分析"闭环管理,以CO模块为核心,集成PP、MM等模块。核算前需配置标准成本控制范围、成本中心等主数据。标准成本通过BOM和工艺路线计算(CK11N),采购和生产过程记录实际成本差异。制造费用通过成本中心归集,作业成本按实际耗用量分配。完工产品按标准成本入库,月末通过KO88结算工单差异,物料分类账(CKMLCP)还原实际成本。整个流程实现FI与CO数据同步,确保账务一致。关键事务码包括CK11N(成本估算)、MIGO(物料移动)、CO11N(报工)等。

金牌架构师 537

python 字符编码

python解释器与文件本编辑的异同如下相同点:前两个阶段二者完全一致,都是将硬盘中文件的内容读入内存,详解如下python解释器是解释执行文件内容的,因而python解释器具备读py文件的功能,这一点与文本编辑器一样不同点:在阶段3时,针对内存中读入的内容处理方式不同,详解如下文本编辑器将文件内容读入内存后,是为了显示或者编辑,根本不去理会python的语法,而python解释器将文件内容读入内存后,可不是为了给你瞅一眼python代码写的啥,而是为了执行python代码、会识别python语法)

王献运的博客 1667

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

字符编码详解

走过路过不要错过啊

weixin_46012855的博客 384

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

python编码详解_Python字符编码详解

知识储备三大核心硬件#所有软件都是运行硬件之上的,与运行软件相关的三大核心硬件为cpu、内存、硬盘,我们需要明确三点#1、软件运行前,软件的代码及其相关数据都是存放于硬盘中的#2、任何软件的启动都是将数据从硬盘中读入内存,然后cpu从内存中取出指令并执行#3、软件运行过程中产生的数据最先都是存放于内存中的,若想永久保存软件产生的数据,则需要将数据由内存写入硬盘文本编辑器读取文件内容的流程#阶段1、...

weixin_31807383的博客 433

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

转1:Python字符编码详解

...

老猿Python 3175
上一篇: OpenCV-Python学习基础知识!
下一篇: Python中import机制!
Python_trys
博客等级 码龄2年 4369粉丝 377原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值