Python字符和编码
1. 字符和编码
背景
因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。最早的计算机在设计时采用8个比特(bit)作为一个字节(byte)。
由于计算机是美国人发明的,因此,最早只有127个字符被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII
编码,比如大写字母A
的编码是65
,小写字母z
的编码是122。
但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312
编码,用来把中文编进去。
你可以想得到的是,全世界有上百种语言,日本把日文编到Shift_JIS
里,韩国把韩文编到Euc-kr
里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。
因此,Unicode应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。
Unicode标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。现代操作系统和大多数编程语言都直接支持Unicode。
ASCII编码Unicode编码UTF-8编码
ASCII编码是1个字节,而Unicode编码通常是2个字节。
字母A
用ASCII编码是十进制的65
,二进制的01000001
汉字中
已经超出了ASCII编码的范围,用Unicode编码是十进制的20013
,二进制的01001110 00101101
。
如果把ASCII编码的A
用Unicode编码,只需要在前面补0就可以,因此,A
的Unicode编码是00000000 01000001
。
新的问题又出现了:如果统一成Unicode编码,乱码问题从此消失了。但是,如果你写的文本基本上全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间,在存储和传输上就十分不划算。
所以,本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的UTF-8
编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间。
在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。
用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件。
浏览网页的时候,服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器。
注意:申明了UTF-8编码并不意味着你的.py
文件就是UTF-8编码的,必须并且要确保文本编辑器正在使用UTF-8 without BOM编码
2. 函数
对于单个字符的编码,Python提供了ord()
函数获取字符的整数表示,chr()
函数把编码转换为对应的字符:
>>> ord('A')
65
>>> ord('中')
20013
>>> chr(66)
'B'
>>> chr(25991)
'文'
由于Python的字符串类型是str
,在内存中以Unicode表示,一个字符对应若干个字节。如果要在网络上传输,或者保存到磁盘上,就需要把str
变为以字节为单位的bytes
。Python对bytes
类型的数据用带b
前缀的单引号或双引号表示: x = b'ABC'
以Unicode表示的str
通过encode()
方法可以编码为指定的bytes
,例如:
>>> 'ABC'.encode('ascii')
b'ABC'
>>> '中文'.encode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'
>>> '中文'.encode('ascii')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
在bytes
中,无法显示为ASCII字符的字节,用\x##
显示。
反过来,如果我们从网络或磁盘上读取了字节流,那么读到的数据就是bytes
。要把bytes
变为str
,就需要用decode()
方法:
>>> b'ABC'.decode('ascii')
'ABC'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中文'
如果bytes
中包含无法解码的字节,decode()
方法会报错:
>>> b'\xe4\xb8\xad\xff'.decode('utf-8')
Traceback (most recent call last):
...
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 3: invalid start byte
如果bytes
中只有一小部分无效的字节,可以传入errors='ignore'
忽略错误的字节:
>>> b'\xe4\xb8\xad\xff'.decode('utf-8', errors='ignore')
'中'
要计算str
包含多少个字符,可以用len()
函数:
>>> len('ABC')
3
>>> len('中文')
2
len()
函数计算的是str
的字符数,如果换成bytes
,len()
函数就计算字节数:
>>> len(b'ABC')
3
>>> len(b'\xe4\xb8\xad\xe6\x96\x87')
6
>>> len('中文'.encode('utf-8'))
6
3.格式化字符串
在Python中,采用的格式化方式和C语言是一致的,用%
实现,举例如下:
>>> 'Hello, %s' % 'world'
'Hello, world'
>>> 'Hi, %s, you have $%d.' % ('Michael', 1000000)
'Hi, Michael, you have $1000000.'
格式化整数和浮点数还可以指定是否补0和整数与小数的位数:
print('%2d-%02d' % (3, 1))
3-01
print('%.2f' % 3.1415926)
3.14
有些时候,字符串里面的%
是一个普通字符怎么办?这个时候就需要转义,用%%
来表示一个%
:
>>> 'growth rate: %d %%' % 7
'growth rate: 7 %'
另一种格式化字符串的方法是使用字符串的format()
方法,它会用传入的参数依次替换字符串内的占位符{0}
、{1}
……,不过这种方式写起来比%要麻烦得多:
>>> 'Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125)
'Hello, 小明, 成绩提升了 17.1%'
学习资源来自: https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431664106267f12e9bef7ee14cf6a8776a479bdec9b9000
Python字符和编码的更多相关文章
- python字符编码(二)
一.什么是字符编码 计算机要想工作必须通电,也就是说‘电’驱使计算机干活,而‘电’的特性,就是高低电压(高低压即二进制数1,低电压即二进制数0),也就是说计算机只认识数字 编程的目的是让计算机干活,而 ...
- python 字符编码问题
原因 近期,用Python处理一些中文的字符串,但是用Python读取文件的中文字符和在代码中输入的中文字符,在判断处理时,例如判断“相等”或者“包含”,总是不能判断,相等或者包含都不起作用.看了字符 ...
- python 字符编码练习
通过下面的练习,加深对python字符编码的认识 # \x00 - \xff 256个字符 >>> a = range(256)>>> b = bytes(a) # ...
- Python字符编码讲解
声明:本文参考 Python字符编码详解 在计算机中我们不管用什么语言和程序,最终数据在计算机中的都是字节码(也就是01形式)的形式存在的,如果 计算机直接把字节码显示在屏幕上,很明显一般人看不懂字节 ...
- 深入理解Python字符编码--转
http://blog.51cto.com/9478652/2057896 不论你是有着多年经验的 Python 老司机还是刚入门 Python 不久,你一定遇到过UnicodeEncodeError ...
- [转] Python 字符编码判断
转自:http://www.cnblogs.com/dkblog/archive/2011/03/02/1980644.html 法一: isinstance(s, str) 用来判断是否为一般字符串 ...
- 深入理解Python字符编码
不论你是有着多年经验的 Python 老司机还是刚入门 Python 不久,你一定遇到过UnicodeEncodeError.UnicodeDecodeError 错误,每当遇到错误我们就拿着 enc ...
- python字符编码与文件打开
一 字符编码 储备知识点: 1.计算机系统分为三层: 应用程序 操作系统 计算机硬件 2.运行Python程序的三个步骤 1.先启动python解释器 2.再将python文件当做普通的文本文件读入内 ...
- Python—字符编码转换、函数基本操作
字符编码转换 函数 #声明文件编码,格式如下: #-*- coding:utf-8 -*- 注意此处只是声明了文件编码格式,python的默认编码还是unicode 字符编码转换: import sy ...
随机推荐
- HTML中关于url、scr、href的区别
URL是什么 URL:Uniform Resource Locators(统一资源定位器)的简写,Web浏览器通过URL从Web服务器请求页面. url不是属性,src和href是属性,src用于替换 ...
- python 常用的一些库
AllPairs 2.0.1Appium-Python-Client 0.24asn1crypto 0.24.0attrs 17.4.0AutoItLibrary 1.1bcrypt 3.1.4bea ...
- ASP.NET MVC 视图层-生成链接相关(Html.ActionLink,Url.Action)
1. @Html.ActionLink() 参考 也是使用在chtml模板中,返回参数中指定controller.指定action的所生成的超链接标签<a>标签html文本.如果没有指定 ...
- 记一次成功部署kolla-ansible ocata版本过程
1.安装的docker版本 [root@controller ~]# docker --versionDocker version 17.09.1-ce, build 19e2cf6 2.安装的ans ...
- Delphi 关键字详解
Delphi 关键字详解[整理于 "橙子" 的帖子] absolute //它使得你能够创建一个新变量, 并且该变量的起始地址与另一个变量相同. var Str: ]; S ...
- [A/C 2007] 数据备份(网络流,堆)
[A/C 2007] 数据备份(网络流,堆) 给你N各点的位置和K条链,需要用这些链把2K个点连起来,使得链的总长最短.可以随意选择要链的点.n=100000. 这道题居然可以用堆-- 首先,不能把区 ...
- JAVA进阶----ThreadPoolExecutor机制(转)
http://825635381.iteye.com/blog/2184680 ThreadPoolExecutor机制 一.概述 1.ThreadPoolExecutor作为java.util.co ...
- java枚举enum equal与==
原文链接:https://www.cnblogs.com/xiohao/p/7405423.html 问题 我知道Java枚举会被编译成一个包含私有构造参数和一堆静态方法的类,当去比较两个枚举的时候, ...
- Python 模拟简单区块链
首先这是说明一下这是Tiny熊老师的教程https://www.cnblogs.com/tinyxiong 另外还要说明一下,暑假指导老师让我们做一些关于区块链的应用.这里只是涉及极其简单的模拟,主要 ...
- linux 内核的 switch_to原理
switch_to:这是一个宏,有三个参数prev,next,last 局部变量prev,next:指向进程描述符的内存地址 首先明确的是:last和prev是同一个,用last只是为了理解方便,完全 ...