进制转换问题及编码问题

Part A.编码问题

表格挺清晰的,不过奇怪赞同人少ASCII码-2/10/16进制对照表
这四个我没细看:比较长篇的参考1比较长篇的参考2参考3-廖雪峰py3参考4-廖雪峰py2

一、内容比较复杂,我直接说我常用的

(1)unicode 是最底层的通用编码。
(2)流行的是 utf-8 编码,这是因为utf-8是不定长的。对英文、中文等都友好点。
(3)ASCII 码,长度小范围小,不支持中文。
(4)对于英语字母,UTF-8 编码和 ASCII 码是相同的。
(5)python字符串的类型只有两种 str,bytes 。
(6)python3里面 str 是 unicode 编码。

>>> "我们" == u"我们"
True

(7)python3里面 bytes 类型字符串是根据指定编码 encode生成的,它不是二进制字符串,而是比特流的意思!!bytes 字符串的组成形式,必须是十六进制数,或者ASCII字符。 参考博客

>>> "我们".encode("gbk")
b'\xce\xd2\xc3\xc7'
>>> "我们".encode("utf8")  # 可见gbk、utf-8的编码得到的 bytes 字符串是不同的。
b'\xe6\x88\x91\xe4\xbb\xac'
>>> "我们".encode()   # py3默认编码是utf-8
b'\xe6\x88\x91\xe4\xbb\xac'
>>> "我们".decode("utf8")  # 原本的是 unicode 码,已经是最底层编码了,所以decode会报错。
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'decode'

二、python打印的print

未必是目标编码字符串(二进制),通常是转换过了的。就比如'\x4E'实际打印的是ascii编码或说utf8编码的N

>>> my_data = '\x4E'  # ascii码对应标:十六进制对应的图形是"N"
>>> my_data
'N'

>>> my_data = b'\x4E'
>>> my_data
b'N'

>>> my_data = 0x4E  # ascii码对应标:十六进制对应的十进制是78
>>> my_data
78

>>> chr(78)  # 把一个十进制转换成ASCII码表中对应的单个字符
'N'
>>> ord('N') # 把ASCII码表中的字符转换成对应的十进制
78

三、十进制与ascii的转换

1、chr():把一个十进制转换成ASCII码表中对应的单个字符

>>> chr(98)
'b'
>>> chr(97)
'a'

2、ord():和chr相反,把ASCII码表中的字符转换成对应的十进制

>>> ord('b')
98
>>> ord('c')
99

Part B.进制转换

一、不同进制之间的转换

总起1:很不错的博客,也很全面

1、二进制与十六进制之间的转换:用binascii库

二进制转为十六进制的函数:binascii.b2a_hex()、binascii.hexlify()
十六进制转为二进制的函数:binascii.a2b_hex()、binascii.unhexlify()

#coding:utf-8
import binascii
a = 'worker'
b = binascii.b2a_hex(a)  # 二进制转为十六进制
print(b)  # 输出:776f726b6572

t = binascii.a2b_hex(b) # 十六进制转为二进制。与b2a_hex相反。
print(t)  # 输出 worker

c = binascii.hexlify(a) # 二进制转为十六进制。和b2a_hex()一样
print(c)  # 输出:776f726b6572

d = binascii.unhexlify(c)  #  十六进制转为二进制。和a2b_hex()一样。
print(d)  # 输出:worker
2、十进制与其它进制的转换:python内置函数

(1)hex() 把10进制转换成16进制

>>> hex(88)
'0x58'
#把浮点型转换成16进制
>>> 1.23.hex()
'0x1.3ae147ae147aep+0'

(2)bin():把十进制整型转换成二进制字符

>>> bin(88)
'0b1011000'
>>> bin(33)
'0b100001'

(3)oct():把十进制转换成八进制字符

>>> oct(500)
'0764'
>>> oct(488)
'0750'
3、读取任意进制字符串:np.fromstring()

参考官方参考博客
numpy.fromstring(string, dtype=float, count=-1, sep=’’)
参数说明:

string : str 输入字符串
dtype : data-type, optional 控制生成的array的dtype。如果是二进制输入,就一定要输入输出相匹配,此时通常是np.uint8。
count : int, optional 读取多少个数据。可以不用管。
sep : str, optional 分割符

例子:

>>> np.fromstring('1 2', dtype=int, sep=' ')
array([1, 2])
>>> np.fromstring('1, 2', dtype=int, sep=',')
array([1, 2])

>>> np.fromstring('\x60', dtype=np.uint8)
array([96], dtype=int8)

二、概念

1、普通文本文件与二进制文件的差别

读取时的区别:二进制可以每个字符为一位,不会出现中文字符需要占据多位问题,但是需要进行encode才能知道具体的字符串。

在python的load_word2vec_format函数里面有具体区别的代码:
gensim.models.KeyedVectors.load_word2vec_format(‘vectors.bin’, binary=True)

注:c语言的fgetc函数,暂时我觉得它不能够直接读取中文字符,不过可以读取中文字符的二进制格式。具体的我要实践后再确定。

三、python3 遇到的问题及解法

1、解码时报错
(1)原因:某些文件,按照字节大小直接截断,导致编码有问题。
(2)报错例子:

'utf-8' codec can't decode byte 0xe6 in position 0: unexpected end of data

(3)解决方案1:参考
二进制读取文件,读取一行后,就行解码。解码不成功就 ignore,全称 ignore 模式。或者open 函数里面参数设置为 ignore 也行。

with open(in_path, "rb") as f_in:
	for line inf_in:
	    try:
	        line = line.decode("utf8").strip()
	    except Exception:
	        print("error sentance_cnt", sentance_cnt)
	        print(line)
	        line = line.decode("utf8", errors='ignore').strip()  # 无视解码有问题的模式。默认是strict模式。还有一种是 replace 模式,但不推荐用,它会用一些很奇怪的字符代替无法解码的字符。
	        print(line)

解决方案2——弃用:参考
之前py2.7还流行时使用的,之前我用过可以。现在可能没什么用了。只当记录一下吧。

import sys
reload(sys)
sys.setdefaultencoding('utf-8')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值