3rsh1
/single dog/college student/ctfer
3rsh1's Blog

python内bytes和str类型浅谈

python内bytes和str类型浅谈

str就是字符串类型,主要的编码方式就是’utf-8’,英文字母用一个字节表示,汉字用三个字节表示。utf-8编码长度是可变的,英文只需要一个字节,汉字可能需要三个字节。且兼并了ascii码。

bytes就是比特流即编码成字符串之前的形式,同样应该是有意义的比特流。但是为了ide显示方便,通常会显示为十六进制的形式。

#在使用bytes方法时,必须明确encoding参数的值。
b=bytes('a',encoding='utf-8')
print(a)#b'a',我觉得是因为好显示才直接显示a的。
b=bytes('中',encoding='utf-8')
print(b)#b'\xe4\xb8\xad',b表示比特流

如果给出的字符串都是 ASCII 字符,那么直接在字符串前面添加b前缀就可以转换成 bytes。

在bytes类的方法中有个decode()方法是把bytes类型的比特流转化成str类型的字符串。

语法为:bytes.decode(encoding="utf-8", errors="strict")

encoding -- 要使用的编码,如"UTF-8"。
errors -- 设置不同错误的处理方案。默认为 'strict',意为编码错误引起一个UnicodeError。 其他可能得值有 'ignore', 'replace', 'xmlcharrefreplace', 'backslashreplace' 以及通过 codecs.register_error() 注册的任何值。

在str类的方法中有个encode()方法是把str类型的字符串转化成bytes类型的数据流。(和bytes.decode()的参数一样。)

a=str.encode('中',encoding='utf-8',errors='strict')
print(a)#b'\xe4\xb8\xad'
b=bytes.decode(a,encoding='utf-8')
print(b)#中

网页编码:

对于网页编码来说,print出来的应该是bytes类型的编码,这时候若是想要转化成可视化状态,则需要bytes的decode函数。

import requests
url='https://www.baidu.com'
a=requests.get(url)
print(a)#单纯a的话返回的响应码。
print(a.content)#返回bytes类型的网页。
print(bytes.decode(a.content,'utf-8'))#返回正常网页

文件读取:

因为python3中,要求传入的值为str类型,而不是bytes类型,open函数自带encoding方法。
解决方法:

with open("test","wb") as w:    
    w.write("123")

同理,read函数也是一样,写成rb,就可以兼容2与3了。

十六进制转化问题:

print(bytes.hex(b'abcdef'))#616263646566
print(bytes.fromhex('616263646566'))#b'abcdef'
print(bytes.fromhex('0102030405'))#b'\x01\x02\x03\x04\x05'

对于bytes.hex(),接受一个bytes类的值,转化成十六进制字符串。

对于bytes.fromhex(),接受一个str类型的十六进制字符串,转化成bytes类型的比特流。部分不可打印出来的字符串用十六进制来表示。

import binascii
print(binascii.hexlify(b'abcde'))#b'6162636465'
print(binascii.b2a_hex(b'abcde'))#b'6162636465'
print(binascii.unhexlify(b'6162636465'))#b'abcde'

在bytes流下:

binascii.hexlity()将字符转化成对应的十六进制字符。binascii.b2a_hex()和这个函数的效果是一样的。

binascii.unhexlity和上面的函数是相反的。

c=ord('a')#97
a=hex(c)#0x61
b=str(a).replace('0','\\')#\x61
print(a)
print(b)
print(int('10',8))#8
print(int('10',2))#2
print(int('10',16))#16
print(chr(0x5c))#/
print(chr(92))#/

1.ord(i) i只能是单个字符,比如说a,b,c等。返回的结果是字符的ASCII值。

2.hex(i) i只能是十进制数,返回该十进制数的十六进制字符串,带0x

3.int(m,base=n) m可以是字符串或者数字,这里只讨论是字符串的形式。n表示二进制或者八进制或者十六进制,返回对应进制的转化值。

4.chr(i) 这里的i表示十进制数或者十六进制数,返回对应的ASCII字符,这里的i不可超过255。

文件编码问题:

b'xxx'这种形式叫做字节码。其中xxx可以是字符也可以是\xnn这杨的十六进制表示,nn的范围是00-FF。

如果想代码的形式修改字节码中的某个字节可以如下修改:

b='abc\x64'
print(b)#b'abcd'
d=bytearray(b)
d[0]=100
print(d)#bytearray(b'dbcd')

字节可以通过一些转码放置转化为字符串。decode(),将字节串转化为字符串;encode(),将字符串转化为字节串。类比于:最开始的形式是字符串,然后对字符串做一些处理,变成字节码等编码形式。

刚又发现了个神奇的函数:

c='和'
print(c.encode('utf-8'))#b'\xe5\x92\x8c'
print(c.encode('gbk'))#b'\xba\xcd'
d=b'\xba\xcd'
d1=b'\xe5\x92\x8c'
print(d.decode('gbk'))#'和'
print(d1.decode('utf-8'))#'和'

如果编码和解码用了不同的编码方式,就会产生乱码,甚至转换失败。因为每种编码方式包含的字节种类数目不同,

img

https://www.3rsh1.cool/wp-content/uploads/2020/04/wp_editor_md_9cacc770f7785ed228029a85a3ed072f.jpg

也就是说Unicode更像是一个中间形式即一个字符集,Unicode根据对应关系可以翻译为字符串。而ASCII编码或者gbk编码则是将其转换成字节串的形式便于存储,如果进行解码操作的话就会重新变成Unicode形式然后翻译到可辨识的文字到显示器上。

utf-8 是对 unicode 存储的实现方式,unicode 只定义字符对应的数字,但没有规定这些数字如何存储起来。

下面开始步入正题:

第一种:ASCII码

一半是日常生活中用到的字符,另外一半则是ASCII拓展字符。对英文来说很方便但是对于汉字来说存储空间远远不够。

https://www.3rsh1.cool/wp-content/uploads/2020/04/wp_editor_md_77c184ff31a979fa5de462fecda058d5.jpg

第二种: GBK 和 GB2312

因为ASCII码无法表示汉字,故又有了另外一种编码方式来把汉字和数字对应起来。一般用两个字节表示一个汉字。GBK是GB2312的拓展字符集,包含繁体字。

第三种:Unicode

那么这样的话每个国家就会有一种编码集非常不方便。

Unicode把所有国家的字符集合到了一起来。大部分的字符需要用两个字节来表示,但是生僻字需要用四个字节来表示。如果你用的全部是英文但是用了Unicode编码方式来保存的话,空间占了ASCII的一倍多并不节省空间。

第四种:utf-8:

utf-8是变长的Unicode编码形式,长度在1-3个字节之间,生僻字可能会用到4-6个字节。

在计算机的内存中,统一使用Unicode编码方式。当要保存到硬盘或者要传输时会被转化成utf-8编码形式,或者其他的编码形式。

用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件。


23点32分 2020年6月6日 补充:

Unicode编码只是将将字母和数字汉字等进行编号,就先你给“和”赋予编码为1一样。
utf-8,-16,-32等,则是由编码到存储形式上的编码,那前面的例子说,“和”字的编码为1,那么如果是按照utf-8编码来存储的话,存储在物理存储介质上的内容就是“\x01”。而其余的编码方式也是如此,只是在存储介质上编码的方式不同而已。


发表评论

textsms
account_circle
email

3rsh1's Blog

python内bytes和str类型浅谈
python内bytes和str类型浅谈 str就是字符串类型,主要的编码方式就是'utf-8',英文字母用一个字节表示,汉字用三个字节表示。utf-8编码长度是可变的,英文只需要一个字节,汉字可能需要…
扫描二维码继续阅读
2020-04-19