str ,bytes, bytearray

本期教程凡哥给大家从字符串的各种操作说起。 然后讲解了常见的字符集与编码方式,最后我们讲了在Python中的二进制对象bytes跟bytearay

String 字符串

因为C语言出现的年代比较早, 那个时候,编程主要用于工业,面向过程操作, 很少需要处理字符串, 所以用C进行字符串处理就会比较麻烦。 在Python中进行字符串处理就很方便。

# 声明一个字符串
sent = "I am Fange"
sent
'I am Fange'
type(sent)
str
# 获取字符串的长度
len(sent)
10
# 获取特定位置的元素
sent[0]
'I'
# 我们取其中一个字符,返回的仍然是string类型
type(sent[0])
str
# 获取倒数第二个字符
sent[-2]
'g'
# 获取子字符串
sent[2:4]
'am'
# 字符串反转
sent[::-1]
'egnaF ma I'
# 字符串拼接

sent2 = " @CloudRiver"
sent + sent2
'I am Fange @CloudRiver'
# 字符串替换 , 原字符串不变
print(sent.replace("Fange", "凡哥"))
sent
I am 凡哥





'I am Fange'
# 这里是jupyter notebook中的一个小功能
# 查看文档
help(str.replace)
Help on method_descriptor:

replace(...)
    S.replace(old, new[, count]) -> str

    Return a copy of S with all occurrences of substring
    old replaced by new.  If the optional argument count is
    given, only the first count occurrences are replaced.
# 你也可以查看所有的字符串操作
# help(str)
# 拼接字符串
",".join(["1", "2", "3"])
'1,2,3'
# 根据分隔符 分割字符串
"1,2,3".split(",")
['1', '2', '3']
# 帧头帧尾 数据模拟提取

data_str = "START,12, 47, 298.123,END"

print("Is start with 'START' : %s"%data_str.startswith("START"))
print("Is start with 'END' : %s"%data_str.endswith("END"))
data = data_str.split(',')
print("data list = \n", data)
Is start with 'START' : True
Is start with 'END' : True
data list = 
 ['START', '12', ' 47', ' 298.123', 'END']
# 数值提取
x = int(data[1])
y = int(data[2])
value = float(data[3])

print("data: x = %d, y = %d, value = %d"%(x, y, value))
data: x = 12, y = 47, value = 298

字符集与编码方式

Ascii字符集

在早期的计算机时期,电脑只能识别英文的字母与标点符号。 于是就用了 ASCII字符集, 用0-255之间的数字就可以表示所有的字符,实际上还有空余。

ascii

Unicode字符集

后面随着计算机的发展,电脑普及到越来越多的国家跟地区,同时电脑的编码就需求支持当地的语言,也包括我们的中文编码的支持。

other language support

... 中间略过一段GBK编码历史 ···

关于计算机的编码的详细信息跟历史可以查看知乎的这篇文章 Unicode 和 UTF-8 有何区别?

后来宇宙终极的字符集出现了Unicode字符集

一些unicode编码样例

sample unicode

Unicode就像一个电话本,标记着字符和数字之间的映射关系。Joel称之为「神奇数字」,因为它们可能是随机指定的,而且不会给出任何解释。官方术语是码位(Code Point),总是用U+开头。理论上每种语言中的每种字符都被Unicode协会指定了一个神奇数字。例如希伯来文中的第一个字母א,是U+2135,字母A是U+0061。

Unicode只是一个用来映射字符和数字的标准。它对支持字符的数量没有限制,也不要求字符必须占两个、三个或者其它任意数量的字节。 Unicode本身并不制定二进制的存储方式,它只是说, 这个编号对应的是这个字符。

UTF编码方式

Unicode如何被编码成内存中的字节,这是UTF(unicode transform formats) UFT编码方案所要解决的问题。 流行的UTF编码方案有两种,一种是UTF-8 另外一种是UFT-16.

UTF-8编码被称作可变长度编码,用一个字节来表示0-127号的字符,跟之前的US-ASCII完全兼容。这意味着1980年代写的文档用UTF-8打开一点问题都没有。只有128号及以上的字符才用2个,3个或者4个字节来表示。

unicode 与 uft-8编码之间的映射

unicode 与 uft-8编码之间的映射

另一个流行的可变长度编码方案是UTF-16,它使用2个或者4个字节来存储字符。然而,人们逐渐意识到UTF-16可能会浪费存储空间。

拓展阅读

学点编码知识又不会死:Unicode的流言终结者和编码大揭秘

网页编码就是那点事

Btyes 字节(bytes)与字节数组(bytearray)

什么是字节?

之前我们提到过,用不同的字符集来表示不同的字符, 然后字符集通过特定的二进制编码(encode)方式来转换为内存中的字节存储。 二进制数据通过反编码(decode)获取到我们的字符串。

那再Python中是有专门的字节数组对象。

什么是字节? 字节(字节数组)是二进制数据组成的序列,其中每个元素由一个字节二进制组成。

1 byte(字节) = 8 bit(位) = 2 位16进制数值

取值范围 0 - 255.

bytes

我们换一种方式初始化字符串 使用unicode编码来表示不同的字符。

my_string = "Hi \u2119\u01b4\u2602\u210c\xf8\u1f24"
my_string
'Hi ℙƴ☂ℌøἤ'
type(my_string)
str

在python中字节数组的声明方式跟字符串的声明方式很像, 就是在字符串前面加一个b

bytes_arr = b"hello"

type(bytes_arr)
bytes
bytes_arr
b'hello'
bytes_arr == (b'h' b'e' b'l' b'l' b'o' )
True
# 打印出bytes_arr中的数值, 我们可以看到他的类型是数值
for byte in bytes_arr:
    print(byte)
104
101
108
108
111
# 我们可以换一种方法来初始化 bytes对象
bytes_arr2 = bytes([104, 101, 108, 108, 111])
print(bytes_arr2)
b'hello'
chr(bytes_arr[0])
'h'
# 我们测试一下汉字转换为字节
b'凡哥'
  File "<ipython-input-19-b780e2718ca4>", line 2
    b'凡哥'
         ^
SyntaxError: bytes can only contain ASCII literal characters.

这里提示我们bytes类型只可以包含ASCII编码的字符。

因为默认的bytes编码方式是ascii,不支持中文。 如果我们想让他支持中文应该怎么办?在初始化的时候需要使用别的编码方式。

反编码 decode 字节转换为字符串

2 = bytes("凡哥",encoding='utf8')  #必须制定编码格式

b2
b'\xe5\x87\xa1\xe5\x93\xa5'

我们可以看到,每个汉字在utf8编码中都会占据三个字节 其中 对应的是 \xe5\x87\xa1 对应的是\xe5\x93\xa5

print(b2)

# 我们将其打印看到的也是其编码
b'\xe5\x87\xa1\xe5\x93\xa5'
# 如何将bytes对象变回我们之前的字符
# 我们需要重新解码 decode
fg_str = b2.decode(encoding="utf8")
print(fg_str)
type(fg_str)
凡哥





str
# 我们来做一下bytes的数值对比
b2[1] == b'\x87'
False
b2[1]
135
# 可以看到并不能对比, 原因是?
# 我们来看一下各自的类型

print(type(b2[1]))
print(type(b'\x87'))
<class 'int'>
<class 'bytes'>

一个是整数一个是bytes类型怪不得不可以。 所以正确的比对姿势应该是:

print(b2[1] == b'\x87'[0])
print(bytes([b2[1]]) == b'\x87')
True
True
# 这里我们尝试变更一下其中一个数值
bytes_arr[0] = b'w'[0]
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-64-e462446fa7d0> in <module>()
      1 # 这里我们尝试变更一下其中一个数值
----> 2 bytes_arr[0] = b'w'[0]


TypeError: 'bytes' object does not support item assignment

bytearray 字节数组

可以看到bytes对象在声明之后,就不可以更改其中的值, 类似我们之前提到过的tuple类型。

那有没有可以更改的数据类型, 这里我们就要提到bytearray, 类比我们之前讲过的list类型。

ba = bytearray(b'hello')
ba[0:1] = b'w'
print(ba)
bytearray(b'wello')
ba = bytearray(b'hello')
ba[0] = b'w'[0]
print(ba)
bytearray(b'wello')

字节数组的操作与数组操作类似,这里我们不做过多讲解。

延伸阅读

http://blog.csdn.net/yatere/article/details/6606316

https://www.cnblogs.com/skiler/p/6687337.html

Python 中的字节与字节数组 http://python.jobbole.com/84839/

Copyright 杭州云江科技有限公司 2017 all right reserved,powered by Gitbook该文件修订时间: 2018-04-02 09:53:14

results matching ""

    No results matching ""