Python | python基础(三) - 字符串和编码

字符串和编码

编码

编码是什么?

计算机概论知识: xxxx

计算机底层是0,1代码

计算机用户使用却是实际字符,符号

编码就是 字符,符号 和 01码的对应关系

Ascll码是什么?

因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。

最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255(二进制11111111=十进制)

如果要表示更大的整数,就必须用更多的字节。比如两个字节可以表示的最大整数是65535,4个字节可以表示的最大整数是4294967295。
由于计算机是美国人发明的,因此,最早只有127个字符被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122。

但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去。

全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。

ascll码 美国人编码,127个字符,大小写字母和一些符号
中文 GB2312 中文至少需要2个子节
Unicode编码 综合所有语言的一套编码,Unicode标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。现代操作系统和大多数编程语言都直接支持Unicode。
编码 特性
1 ASCLL码与Unicode码的区别
ascll码 编码是1个子节表示一个字符 ,如 A字符是65,二进制01000001
unicode码 unicode码通常是2个子节表示一个字符

⚠️ 注意字符0数字0是不一样的

字符0用ascll码是48,二进制的00110000

汉字 ,超出了acsll码可以表示的范围,因此不能用acsll码表示中文

可以使用Unicode码表示 ,十进制是20013,二进制01001110 00101101

编码就是二进制的码制的使用,本质还是01进制代码,只不过不是表示的数,而是符号


utf-8码是什么?

为了解决这个问题,要引入 UTF-8字符编码

把Unicode编码变为可以伸缩的编码,达到节约空间的效果

UFT-8根据不同的数字大小分为1-6个子节,如

  • 常用的英文,编码为1个子节,符合ascll码
  • 汉字通常是3个子节,只有很生僻的字会用到4-6个子节,因为汉字数库大,要用的编码表示量也大
字符 ACSLL Unicode UFT -8
A 01000001 00000000 01000001 01000001
x 01001110 00101101 11100100 10111000 10101101

使用utf-8码的好处有哪些?

  • 传输的文本有很多的英文字符,使用UFT-8编码可以大大减少代码量,节约空间
A 01000001 00000000 0 1000001 01000001
字符 ACSLL Unicode UFT -8
x 01001110 00101101 11100100 10111000 10101101

💁‍♂️计算机系统通用的字符编码工作方式

内存中:统一使用Unicode编码

硬盘中,或者传输,就需要转换为UFT-8编码

也就是用记事本编辑文字的时候,这个时候是UFT-8字符正在被转换为Unicode码保存到内存中,当编辑完成的时候,再把unicode码转换为UFT-8码到文件

可见 内存与硬盘的区别

通俗地说,硬盘就相当于一个工厂的仓库,而内存就是工厂的车间。所有的资料都是存在仓库,只有拿到车间才能进行生产,当车间位置不够时,就会调用一部分仓库来做为车间,这就叫作虚拟内存。
硬盘里的资料不会由于关机或停电而丢失,而内存关机后资料也就没有了。硬盘的容量一般是按GB为单位,而内存容量较小,一般以MB为单位,但内存的读写速度要远远高于硬盘。
所以说,硬盘80G就是硬盘,内存512M就是指的内存条是512M。如果不清楚,打开电脑机箱看一下,这两样东西都是很明显可以看到的。

比如此时一个硬盘(比如移动硬盘)上面有一个记事本文本文件,这个时候是UTF-8编码,当你需要插入电脑时,插入时,电脑会读取硬盘上面的UTF-8编码,先转换为Unicode编码(这是因为计算机内存要读取信息,进行处理),当处理完毕,就再转换为UTF-8编码,这样才算是把这个硬盘上面的文件放到你的电脑上面,因此这个是需要转化的,需要一定时间,所以当遇到比较大的文件,把文件复制到计算机中,会看到一个计算机正在复制的一个缓冲过程,这个过程就是计算机内存在处理文件

image

python字符串

在python3中字符串是以Unicode编码的 (所以Python是支持多语言的)

python中常见编码函数有哪些?

对于单个字符编码

  1. ord(): 获取字符的整数(把字符转化为整数)
  2. chr(): 把编码转化为字符

Python 的字符串类型为str

内存中用Unicode表示

Example: 硬盘 或 外部,要把 str ➡ 以子节为单位的bytes

>>> ord('A')
65
>>> ord('中')
20013
>>> chr(66)
'B'
>>> chr(25991)
'文'

如果知道字符的整数编码,还可以用十六进制这么写str:

>>> '\u4e2d\u6587'
'中文'

python bytes数据类型

表示: 用带b的前缀单引号或双引号表示 ➡ x = b’ABC’

⚠️ 要注意区分'ABC'和b'ABC',前者是str,后者虽然内容显示得和前者一样,但bytes的每个字符都只占用一个字节


🔺为字符指定编码

以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)

对于上述报错:

纯英文的str可以用ASCII编码为bytes,内容是一样的,

含有中文的str可以用UTF-8编码为bytes。含有中文的str无法用ASCII编码,因为中文编码的范围超过了ASCII编码的范围,Python会报错。

🔺将编码转为字符

在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

字符串相关函数

1、len()

作用: 计算str包含字符数

>>> len('ABC')
3
>>> len('中文')
2

⚠️注: len()函数计算的是str的字符数,如果换成bytes,len()函数就计算字节数

测试:

# 测试英语字母
>>> 'ABC'.encode('utf-8')
b'ABC'
>>> len('ABC'.encode('utf--8'))
3
# 测试中文汉字
>>> '中文'.encode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'
>>> len('中文'.encode('utf-8'))
6

上述可知:

  • 1个中文字符经过UTF-8编码后通常会占用3个字节
  • 而1个英文字符只占用1个字节。

注意事项和细节:

  1. 持之以utf-8编码转换str与bytes
  2. 源码含中文,保存指定uft-8编码

当Python解释器读取源代码时,为了让它按UTF-8编码读取,我们通常在文件开头写上这两行

#!/usr/bin/env python32
# -*- coding: utf-8 -*

第一行注释是为了告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释;

第二行注释是为了告诉Python解释器,按照UTF-8编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。


申明了UTF-8编码并不意味着你的.py文件就是UTF-8编码的,必须并且要确保文本编辑器正在使用UTF-8 without BOM编码:

在这里插入图片描述 在这里插入图片描述

格式化

为什么需要格式化?

最后一个常见的问题是如何输出格式化的字符串。我们经常会输出类似'亲爱的xxx你好!你xx月的话费是xx,余额是xx'之类的字符串,而xxx的内容都是根据变量变化的,所以,需要一种简便的格式化字符串的方式。

在这里插入图片描述

如何在python中使用格式化?

在Python中,采用的格式化方式和C语言是一致的,用%实现,举例如下:

>>> 'Hello, %s' % 'world'
'Hello, world'
>>> 'Hi, %s, you have $%d.' % ('Michael', 1000000)
'Hi, Michael, you have $1000000.'

你可能猜到了,%运算符就是用来格式化字符串的。在字符串内部,%s表示用字符串替换,%d表示用整数替换,有几个%?占位符,后面就跟几个变量或者值,顺序要对应好。如果只有一个%?,括号可以省略。

常见的占位符

占位符 替换内容
%d 整数
%f 浮点数
%s 字符串
%x 十六进制整数

format()方法

其中,格式化整数和浮点数还可以指定是否补0和整数与小数的位数

另一种格式化字符串的方法是使用字符串的format()方法,它会用传入的参数依次替换字符串内的占位符{0}、{1}……,不过这种方式写起来比%要麻烦得多

>>> 'Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125)
'Hello, 小明, 成绩提升了 17.1%'

总结提升:

1、一般格式化方法

*** %d, *** %s + % + (ttt,ttt)         

*** : 是实际输出的

tttt: 是实际输出用来替换格式符 %d /%s

2、格式化方法 format()

'xxx{0},xxx{1:.1f}%.' . format('tttt',xxx.xxx)

测试:

'hi {0}, nice to meet u ,you height are {1:.1f} cm, ur weight are {2:.1f} kg' .format('mike',178.55,85.55)

结果:

在这里插入图片描述


练习

要求: 小明的成绩从去年的72分提升到了今年的85分,请计算小明成绩提升的百分点,并用字符串格式化显示出xx.x%,只保留小数点后1位。

# -*- coding: utf-8 -*-
s1 = 72
s2 = 85
r = (s2-s1) /72 * 100
name = '小明'
print('%s的成绩相比之前提升%.1f%%个百分点' % (name,r))

运行结果:

在这里插入图片描述

⚠️ 格式符的写法
%s 而不是 s% ,注意括号,和符号的输入法状态

posted @ 2021-06-05 23:26  茶哩哩  阅读(574)  评论(0编辑  收藏  举报