当前位置: 首页 > news >正文

python整数类型进制表示_Python数据类型:bytes

bytes 类型

在 Python 2 中,有两种类型的字符代表字符串,分别是 Strings 和 Unicode。默认将 Strings 以 utf-8 编码成 bytes 类型,而不是使用 unicode 编码(Python 3 已经把 String 使用 Unicode 编码,Unicode 就是 string,而 bytes 就是 bytes),且存在一个类型为 Unicode 类型。

>>> u'徐' # 显示字符 Unicode code, 十六进制

u'\u5f90'

>>> type(u'徐')

>>> str('中')

'\xe4\xb8\xad'

>>> bytes('中')

'\xe4\xb8\xad'

>>> type(str('中'))

str

>>> type(bytes('中'))

str

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

>>>u'徐'# 显示字符 Unicode code, 十六进制

u'\u5f90'

>>>type(u'徐')

>>>str('中')

'\xe4\xb8\xad'

>>>bytes('中')

'\xe4\xb8\xad'

>>>type(str('中'))

str

>>>type(bytes('中'))

str

可以看到 Python 2 中 strings 等同于 bytes 类型。

Python 3 最重要的新特性大概要算是对文本和二进制数据作了更为清晰的区分。在内存中的 str 类型就是 Unicode(具体 str 类型存储到磁盘或通过网络发送出去时可以是 utf8 编码后的二进制数据),二进制数据则由 bytes 类型表示。字符串是以字符为单位进行处理的,bytes 类型是以单个字节作为基本元素(8 位,取值范围 0-255)为单位处理的。

bytes 对象是由单个字节构成的不可变序列,可以把 bytes 看作是一个特殊的数组,由连续的字节(byte)组成,单字节最大数不能超过 255,具有数组的切片,迭代等特性。 由于许多主要二进制协议都基于 ASCII 文本编码,因此 bytes 字面值和表示法是基于 ASCII 文本的,bytes 对象提供了一些仅在处理 ASCII 兼容数据时可用,并且在许多特性上与字符串对象紧密相关的方法。

bytes 对象只负责以二进制字节序列的形式来存储数据,至于这些数据到底表示什么内容(字符串、数字、图片、音频等),完全由程序的解析方式决定。如果采用合适的字符编码方式(字符集),字节串可以恢复成字符串;反之亦然,字符串也可以转换成字节串。

总结来说,在 Python 3 版本中,字符串是以 Unicode 编码的,也就是说,Python 的字符串支持多语言,例如:

>>> print('包含中文的str')

包含中文的str

1

2

>>>print('包含中文的str')

包含中文的str

对于单个字符的编码,Python 提供了ord()函数获取字符在 Unicode 中的十进制整数表示,chr()函数把编码转换为对应的字符:

>>> a = '徐'

>>> ord(a) # 返回一个字符的 Unicode code

24464

>>> chr(24464) # 返回一个 Unicode code 对应的字符

'徐'

1

2

3

4

5

>>>a='徐'

>>>ord(a)# 返回一个字符的 Unicode code

24464

>>>chr(24464)# 返回一个 Unicode code 对应的字符

'徐'

chr()函数能接受 Unicode code 的形式可以是十进制,二进制,十六进制等,效果都是一样的:

>>> chr(24464), chr(0x5f90), chr(0b101111110010000) # 0x 表示十进制, 0b 表示二进制

('徐', '徐', '徐')

1

2

>>>chr(24464),chr(0x5f90),chr(0b101111110010000)# 0x 表示十进制, 0b 表示二进制

('徐','徐','徐')

怎么转换对应进制呢?Python 也提供了对应的方法相互转换。

# bin 方法可以把十进制转为二进制

>>> bin(24464)

'0b101111110010000'

# hex 方法可以把十进制转为二进制

>>> hex(24464)

'0x5f90'

# int 方法可以把二进制或十六进制转为十进制

>>> int(0x5f90), int(0b101111110010000)

(24464, 24464)

1

2

3

4

5

6

7

8

9

10

11

# bin 方法可以把十进制转为二进制

>>>bin(24464)

'0b101111110010000'

# hex 方法可以把十进制转为二进制

>>>hex(24464)

'0x5f90'

# int 方法可以把二进制或十六进制转为十进制

>>>int(0x5f90),int(0b101111110010000)

(24464,24464)

在 Python 中,用非零开头的数字,表示十进制,0x 开头的表示十六进制,0b 开头的表示二进制,需要先识别出对应的进制类型,然后才能做对应的转换,这很好理解;或者你告诉 int 方法,你传入的是什么类型。

>>> int('24464', 10), int('0x5f90', 16), int('0b101111110010000', 2)

(24464, 24464, 24464)

1

2

>>>int('24464',10),int('0x5f90',16),int('0b101111110010000',2)

(24464,24464,24464)

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

>>> '\u5f90'

'徐'

1

2

>>>'\u5f90'

'徐'

两种写法完全是等价的。

由于 Python 3 的字符串类型是 str,在内存中以 Unicode 表示,一个字符对应若干个字节。如果要在网络上传输,或者保存到磁盘上,就需要把 str 变为以字节为单位的 bytes,我们可以通过字符串来创建 bytes 对象,或者说将字符串转换成 bytes 对象。bytes 类型的数据非常适合在互联网上传输,可以用于网络通信编程;bytes 也可以用来存储图片、音频、视频等二进制格式的文件。

对于 ASCII 字符串,表示 bytes 字面值的语法与字符串字面值的大致相同,只是添加了一个 b 前缀,可以直接使用 b’xxxx’ 赋值创建 bytes 对象,但对于非 ASCII 编码的字符则不能通过这种方式创建 bytes 实例。任何超出 127 的二进制值必须使用相应的转义序列形式加入 bytes 字面值。

原因上面说明过了,由于许多主要二进制协议都基于 ASCII 文本编码,因此 bytes 对象提供了一些仅在处理 ASCII 兼容数据时可用。

>>> d = b'徐'

File "", line 1

SyntaxError: bytes can only contain ASCII literal characters.

>>> d = b'ywnds'

>>> print(d)

b'ywnds'

1

2

3

4

5

6

7

>>>d=b'徐'

File"",line1

SyntaxError:bytescanonlycontainASCIIliteralcharacters.

>>>d=b'ywnds'

>>>print(d)

b'ywnds'

通常我们可以通过调用 bytes() 类(没错,它是类,不是函数)生成 bytes 实例,其值形式为 b’xxxxx’,其中 ‘xxxxx’ 为一至多个转义的十六进制字符串(单个 x 的形式为:\xHH,其中 \x 为小写的十六进制转义字符,HH 为二位十六进制数)组成的序列,由于两个十六进制数码精确对应一个字节,因此十六进制数是描述二进制数据的常用格式(八位二进制数,取值范围 0-255),对于同一个字符串如果采用不同的编码方式生成 bytes 对象,就会形成不同的值。

>>> a = '徐'

>>> b = bytes(a, 'utf-8')

>>> type(b) # 获取 b 类型(如果是 Python 2 这里是 str)

>>> print(b)

b'\xe5\xbe\x90'

>>> bytes(a, 'gb2312')

b'\xd0\xec'

1

2

3

4

5

6

7

8

9

10

11

>>>a='徐'

>>>b=bytes(a,'utf-8')

>>>type(b)# 获取 b 类型(如果是 Python 2 这里是 str)

>>>print(b)

b'\xe5\xbe\x90'

>>>bytes(a,'gb2312')

b'\xd0\xec'

比如上例中的 a 字符串对象,其十进制 unicode code 为 24464,分别使用 ‘utf-8’ 和 ‘gb2312’ 两种编码格式将其转换成 bytes 对象 b 和 c ,结果 b 和 c 的值是完全不同的,由于基于的编码格式不一致,b 和 c 的长度甚至都不相同,前者有 3 个字节长度,后者有 2 个字节长度。

>>> print(len(b), len(c))

3 2

1

2

>>>print(len(b),len(c))

32

除了上面两种方法可以将 Unicode 表示的 str 转换为指定编码的 bytes 类型外,也可以以 Unicode 表示的 str 通过 encode() 方法编码为指定的 bytes,默认为 utf8 编码,例如:

>>> 'ABC'.encode('ascii')

b'ABC'

>>> '中文'.encode('utf-8')

b'\xe4\xb8\xad\xe6\x96\x87'

>>> '中文'.encode('ascii')

Traceback (most recent call last):

File "", line 1, in

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

1

2

3

4

5

6

7

8

>>>'ABC'.encode('ascii')

b'ABC'

>>>'中文'.encode('utf-8')

b'\xe4\xb8\xad\xe6\x96\x87'

>>>'中文'.encode('ascii')

Traceback(mostrecentcalllast):

File"",line1,in

UnicodeEncodeError:'ascii'codeccan'tencodecharactersinposition0-1:ordinalnotinrange(128)

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

在 bytes 中,它总是尝试以 ASCII 编码将数据转成可显示字符,这主要是由于许多主要二进制协议都基于 ASCII 文本编码,因此 bytes 对象提供了一些仅在处理 ASCII 兼容数据时可用。超出 ASCII 可显示范围内的字节用\x##显示,##表示二位十六进制,一个字节。

>>> '中文abc'.encode('utf-8')

b'\xe4\xb8\xad\xe6\x96\x87abc'

1

2

>>>'中文abc'.encode('utf-8')

b'\xe4\xb8\xad\xe6\x96\x87abc'

反过来,一般我们从网络或磁盘上读取的字节流数据就是 bytes。对于 bytes 实例,如果需要还原成相应的字符串,则需要借助内置的解码函数 decode(),借助相应的编码格式解码为正常字符串对象,如果采用错误的编码格式解码,则有可能发生错误。

>>> b'\xe5\xbe\x90'.decode('utf8')

'徐'

>>> b'\xd0\xec'.decode('gb2312')

'徐'

1

2

3

4

>>>b'\xe5\xbe\x90'.decode('utf8')

'徐'

>>>b'\xd0\xec'.decode('gb2312')

'徐'

如果bytes中包含无法解码的字节,decode()方法会报错:

>>> b'\xe5\xbe\x90'.decode('gb2312')

Traceback (most recent call last):

File "", line 1, in

UnicodeDecodeError: 'gb2312' codec can't decode byte 0x90 in position 2: incomplete multibyte sequence

1

2

3

4

>>>b'\xe5\xbe\x90'.decode('gb2312')

Traceback(mostrecentcalllast):

File"",line1,in

UnicodeDecodeError:'gb2312'codeccan'tdecodebyte0x90inposition2:incompletemultibytesequence

如果bytes中只有一小部分无效的字节,可以传入errors='ignore'忽略错误的字节:

>>> b'\xe5\xbe\x90'.decode('gb2312', errors='ignore')

'寰'

1

2

>>>b'\xe5\xbe\x90'.decode('gb2312',errors='ignore')

'寰'

由于 bytes 是序列,因此我们可以通过索引或切片访问它的元素:

>>> d[0]

121

>>> d[0:1]

b'y'

1

2

3

4

>>>d[0]

121

>>>d[0:1]

b'y'

可以发现如果以单个索引的形式访问元素,其会直接返回单个字节的十进制整数,而以序列片段的形式访问时,则返回相应的 bytes 中 ASCII 索引元素。

对于 bytes,我们只要知道在 Python 3 中某些场合下强制使用,以及它和字符串类型之间的互相转换,其它的基本照抄字符串。

由于字符类型的不同,所以你通常会需要两个工具函数来对这两种情况的字符进行转换,以此来确保输入值符合代码所预期的字符类型。

Python 3 中写一个方法,接收 str 或者 bytes,总是来返回 str 类型的数据。如下:

def to_str(bytes_or_str):

if isinstance(bytes_or_str, bytes):

value = bytes_or_str.encode('utf-8')

else:

value = bytes_or_str

# str类型的数据

return value

1

2

3

4

5

6

7

defto_str(bytes_or_str):

ifisinstance(bytes_or_str,bytes):

value=bytes_or_str.encode('utf-8')

else:

value=bytes_or_str

# str类型的数据

returnvalue

同理,我们需要另一个方法,来接收 str 或 bytes ,总是来返回 bytes 类型的数据。

def to_bytes(bytes_or_str):

if isinstance(bytes_or_str, str):

value = bytes_or_str.encode('utf-8')

else:

value = bytes_or_str

# 字节类型的数据

return value

1

2

3

4

5

6

7

defto_bytes(bytes_or_str):

ifisinstance(bytes_or_str,str):

value=bytes_or_str.encode('utf-8')

else:

value=bytes_or_str

# 字节类型的数据

returnvalue

在 Python 3 中,bytes 类型包含的是 8 个比特值的序列,str 是包含 Unicode 字符串。字节和字符串实例不能同时出现在操作符 ‘>’ 或者 ‘+’ 中,这两者无法比较。所以最好使用工具函数来确保程序输入的数据是预期类型。

bytearray

bytearray 对象是 bytes 对象的可变字节数组。bytearray 对象没有专属的字面值语法,它们总是通过调用构造器来创建。

编码和解码十六进制数

如果你只是简单的解码或编码一个十六进制的原始字符串,可以使用binascii模块。例如:

# Initial byte string

>>> s = b'hello'

# Encode as hex

>>> import binascii

>>> h = binascii.b2a_hex(s)

>>> h

b'68656c6c6f'

# Decode back to bytes

>>> binascii.a2b_hex(h)

b'hello'

1

2

3

4

5

6

7

8

9

10

# Initial byte string

>>>s=b'hello'

# Encode as hex

>>>importbinascii

>>>h=binascii.b2a_hex(s)

>>>h

b'68656c6c6f'

# Decode back to bytes

>>>binascii.a2b_hex(h)

b'hello'

类似的功能同样可以在 base64 模块中找到。例如:

>>> h = base64.b16encode(s)

>>> h

b'68656C6C6F'

>>> base64.b16decode(h)

b'hello'

1

2

3

4

5

>>>h=base64.b16encode(s)

>>>h

b'68656C6C6F'

>>>base64.b16decode(h)

b'hello'

大部分情况下,通过使用上述的函数来转换十六进制是很简单的。 上面两种技术的主要不同在于大小写的处理。 函数 base64.b16decode() 和 base64.b16encode() 只能操作大写形式的十六进制字母, 而 binascii 模块中的函数大小写都能处理。

>>> h = base64.b16encode(s)

>>> print(h)

b'68656C6C6F'

>>> print(h.decode('ascii'))

68656C6C6F

1

2

3

4

5

>>>h=base64.b16encode(s)

>>>print(h)

b'68656C6C6F'

>>>print(h.decode('ascii'))

68656C6C6F

在解码十六进制数时,函数 b16decode() 和 a2b_hex() 可以接受字节或unicode字符串。 但是,unicode 字符串必须仅仅只包含 ASCII 编码的十六进制数。

<原文>

如果您觉得本站对你有帮助,那么可以支付宝扫码捐助以帮助本站更好地发展,在此谢过。

相关文章:

  • scada schneider 系统_【原创分享】小白也能DIY物联网系统,程序设计来了!
  • python程序设计试卷_Python程序设计试题库
  • python nameerror错误_python - python regex错误:NameError:未定义名称“ re” - 堆栈内存溢出...
  • 用自底向上算法为一组整数构造一个大根堆。_Polyhedral编译调度算法(1)——Pluto算法...
  • ftp文件夹错误 windows无法访问此文件夹_ftp根目录怎么设置,ftp根目录怎么设置,详细设置方法...
  • 无法列入分布式事务处理_浅谈分布式数据库中的事务
  • 如何用python进行相关性分析_Python 相关性分析 显著性检验
  • idea maven search for class_Maven是什么?为什么使用
  • tensorflow contrib模块_OpenCV DNN 模块-风格迁移
  • python人脸检测代码_10行代码实现python人脸识别
  • python正则表达式教程_Python正则表达式高级使用方法汇总
  • js修改style样式_jsx组件样式隔离的最佳实践
  • 易语言和python混合编程_C语言可以和Python一起混合编程?两者相加无敌了!
  • python粘性拓展_Python Numpy 数组扩展 repeat和tile
  • 麦肯锡ppt模板 306页黑白_图解钢筋、模板、混凝土细部做法,123页PPT可下载!...
  • 【知识碎片】第三方登录弹窗效果
  • android高仿小视频、应用锁、3种存储库、QQ小红点动画、仿支付宝图表等源码...
  • CSS居中完全指南——构建CSS居中决策树
  • Gradle 5.0 正式版发布
  • happypack两次报错的问题
  • JavaScript 基础知识 - 入门篇(一)
  • JS进阶 - JS 、JS-Web-API与DOM、BOM
  • ng6--错误信息小结(持续更新)
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • SegmentFault 社区上线小程序开发频道,助力小程序开发者生态
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • Theano - 导数
  • TypeScript实现数据结构(一)栈,队列,链表
  • unity如何实现一个固定宽度的orthagraphic相机
  • vue学习系列(二)vue-cli
  • 百度小程序遇到的问题
  • 半理解系列--Promise的进化史
  • 分享几个不错的工具
  • 分享自己折腾多时的一套 vue 组件 --we-vue
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • 前端临床手札——文件上传
  • 如何合理的规划jvm性能调优
  • 我建了一个叫Hello World的项目
  • 吴恩达Deep Learning课程练习题参考答案——R语言版
  • 原生js练习题---第五课
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • ###项目技术发展史
  • #Linux(权限管理)
  • $.ajax()参数及用法
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (20)目标检测算法之YOLOv5计算预选框、详解anchor计算
  • (7)STL算法之交换赋值
  • (Redis使用系列) Springboot 使用redis实现接口Api限流 十
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (八)c52学习之旅-中断实验
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (附源码)小程序 交通违法举报系统 毕业设计 242045
  • (每日持续更新)jdk api之FileReader基础、应用、实战