返回顶部
首页 > 资讯 > 后端开发 > Python >Python字符编码是什么
  • 587
分享到

Python字符编码是什么

2023-06-29 18:06:50 587人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

本文小编为大家详细介绍“python字符编码是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Python字符编码是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1. 字符编码简介1.1. ASCIIAS

本文小编为大家详细介绍“python字符编码是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Python字符编码是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

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。参见

另外需要注意的是声明的编码必须与文件实际保存时用的编码一致,否则很大几率会出现代码解析异常。现在的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编码,解码成unicodeu = s.decode('GBK') f = open('test.txt', 'w')# 编码成UTF-8编码的strs = 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')# 写入unicodef.write(u) # 写入str,自动进行解码编码操作# GBK编码的strs = '汉'print repr(s) # '\xba\xba'# 这里会先将GBK编码的str解码为unicode再编码为UTF-8写入f.write(s) f.close()

2.4. 与编码相关的方法

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

import sysimport 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 guessp(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频道。

--结束END--

本文标题: Python字符编码是什么

本文链接: https://lsjlt.com/news/325993.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Python字符编码是什么
    本文小编为大家详细介绍“Python字符编码是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Python字符编码是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1. 字符编码简介1.1. ASCIIAS...
    99+
    2023-06-29
  • Python字符集和字符编码是什么
    这篇文章主要介绍“Python字符集和字符编码是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Python字符集和字符编码是什么”文章能帮助大家解决问题。首先计算机存储的基本单位是字节,由8个比...
    99+
    2023-06-30
  • python字符串的构成及字符编码的细节是什么
    本篇内容主要讲解“python字符串的构成及字符编码的细节是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“python字符串的构成及字符编码的细节是什么”吧!字节与字符计算机存储的一切数据,...
    99+
    2023-06-02
  • python字符编码
    近期接触到python的编码相关的东西,发现自己了解的不是太系统,故通过搜索资料做了一些总结。 字符编码 字符串也是一种数据类型,但是,字符串比较特殊的是还有一个编码问题。 我们知道,计算机内部,所有信息最终都是一个二进制值。每一个二进制位...
    99+
    2023-01-31
    字符 python
  • python字符串编码
    python默认编码   python 2.x默认的字符编码是ASCII,默认的文件编码也是ASCII。   python 3.x默认的字符编码是unicode,默认的文件编码是utf-8。   中文乱码问题   无论以什么编码在内存里显...
    99+
    2023-01-30
    字符串 python
  • Java中字符编码的原理是什么
    Java中字符编码的原理是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1、Java文件编译后形成class这里Java文件的编码可能有多种多样,但Java...
    99+
    2023-06-17
  • JavaScript中的Base64编码字符串是什么
    今天小编给大家分享一下JavaScript中的Base64编码字符串是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。初步...
    99+
    2023-07-05
  • HTML URL字符编码的作用是什么
    HTML URL字符编码的作用是将URL中的特殊字符转换为可识别的编码形式,以确保URL在传输过程中能正确地被解析和处理。URL字符...
    99+
    2023-10-12
    HTML
  • python字符编码与转码
    python 2.x 字符编码与转码打印系统默认编码格式import sys print(sys.getdefaultencoding())UTF-8 转 gbk方式:utf-8--转成--unicode--转成--gbka = "你好" ...
    99+
    2023-01-31
    字符 python
  • Python字符集和字符编码详情
    目录前言字符集和字符编码小结前言 这一次我们分析一下Python的字符串,首先字符串是一个变长对象,因为不同长度的字符串所占的内存是不一样的;但同时字符串又是一个不可变对象,因为一旦...
    99+
    2024-04-02
  • Python中的字符串与字符编码
    Hello,这里是Token_w的博客,欢迎您的到来 今天文章讲解的是Python中的字符串与字符编码,其中有基础的理论知识讲解,也有实战中的应用讲解,希望对你有所帮助 整理不易,如对你有所帮助,希望能得到你的点赞、收藏支持。感谢 ...
    99+
    2023-08-30
    python android 开发语言
  • Python chardet 字符编码判
    使 用 chardet 可以很方便的实现字符串/文件的编码检测。尤其是中文网页,有的页面使用GBK/GB2312,有的使用UTF8,如果你需要去爬一些页面,知道网页编码 很重要的,虽然HTML页面有charset标签,但是有些时候是不对的...
    99+
    2023-01-31
    字符 Python chardet
  • php字符编码转换的方法是什么
    PHP提供了多种方法来进行字符编码转换,常用的方法有:1. 使用mb_convert_encoding函数进行转换:```php$n...
    99+
    2023-10-11
    php
  • mysql数据库默认字符编码是什么
    默认字符编码取决于操作系统:unix/linux:utf8mb4windows:mysql 8.0+:utf8mb4,mysql 5.7-:latin1 MySQL 数据库默认字符编码...
    99+
    2024-04-22
    mysql linux 数据丢失
  • C#字符ASCII码是什么
    这篇文章主要讲解了“C#字符ASCII码是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C#字符ASCII码是什么”吧!C#字符ASCII码很多时候我们需要得到一个英文字符的 ASCII...
    99+
    2023-06-17
  • python 字符编码与转换
    unicode 中文英文默认统一 2个字节ASCII 只有英文和特殊字符 每个占用1个字节 不能存中文每个字节由8个比特(Bit)构成假如一个英文文档是2M,转换为unicode 编码转换,就变成了4M为了解决空间浪费的问题,在unicod...
    99+
    2023-01-30
    字符 python
  • python基础之字符编码
    一 计算机基础知识   二 文本编辑器存取文件的原理(nodepad++,pycharm,word) #1、打开编辑器就打开了启动了一个进程,是在内存中的,所以,用编辑器编写的内容也都是存放与内存中的,断电后数据丢失 #2、要想永久...
    99+
    2023-01-30
    字符 基础 python
  • linux设置字符集编码的方法是什么
    查看当前系统字符集编码:使用命令`locale`查看当前系统的语言环境、字符集编码等信息。修改字符集编码:可以通过修改`/etc/l...
    99+
    2023-05-13
    linux设置字符集 linux
  • 字符编码
    计算机基础 文本编辑器存取文件的原理 1.打开编辑器就打开启动了一个进程,是在内存中,所以,用编码器编写的内容也都存放在内存中的,断电后数据丢失。 2.要想永久保存,需要点击保存按钮:编辑器把内存的数据拴到硬盘上。 3.早我们编写一个...
    99+
    2023-01-31
    字符
  • 快速入手Python字符编码
    前言 对于很多接触Python的人而言,字符的处理和语言整体的温顺可靠相比显得格外桀骜不驯难以驾驭。 文章针对Python 2.7,主要因为3对的编码已经有了很大的改善并且实际原理一样,更改一下操作命令即可...
    99+
    2022-06-04
    字符 快速 Python
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作