Too young, too simple. Sometimes, naive & stupid

系统编程概述(Python)

系统编程概述

字符串方法基础知识

Python的字符串方法本身并非系统相关工具, 但他们频繁现身于绝大多数Python程序,字符串方法保罗用于查找和替换的调用:

1
2
3
mystr = 'xxxSPAMxxx'
mystr.find('SPAM') # 返回首个匹配的位置偏移量
3

1
2
3
mystr = 'xxaaxxaa'
mystr.replace('aa', 'SPAM') # 全局替换
'xxSPAMxxSPAM'

find函数返回子字符串第一个匹配所在的便宜位置,replace函数则完成全局搜索与替换,和所有字符串操作一样,replace函数返回的是新字符串,而不是改变原有字符串(字符串是不可变的).有了这些方法,子字符串可以还原成字符串来处理.

在最新的Python版本中, 如果我们只需要得到”是/否”的回答,那么通常可以用成员判断运算符in(用于测试子字符串是否存在)来替代find函数.去除字符串结尾的空格有多种方法,这在从文件读取文本行时特别有用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mystr = 'xxxSPAMxxx'
'SPAM' in mystr # 子字符串搜索/测试
True

'Ni' in mystr # 没找到时
False

mystr.find('Ni')
-1


mystr = '\t Ni \n'
mystr.strip() # 去除空白分隔符
'Ni'
mystr.rstrip() # 去除空白分隔符(在右侧进行)
'\t Ni'

字符串方法为大小写转换等提供了有用的函数,另外还有一个名为string 的标准库模块,里面定义了一些有用的预设变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mystr = 'SHRUBBERY'
mystr.lower() # 大小写转换器
'shrubbery'

mystr.isalpha() # 内容测试
True
mystr.isdigit()
False


import string # 环境预设: 可在'in'等语句中使用
string.ascii_lowercase
'abcdefghijklmnopqrstuvwxyz'
string.whitespace # 空白分隔符
' \t\n\r\x0b\x0c'

还有一些方法,可以用字符串作为分隔符来分割原始字符串,也可以用子字符串将它们连接起来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
mystr = 'aaa,bbb,ccc'		# 分割为子字符串组成的列表
mystr.split(',')
['aaa','bbb','ccc']

mystr = 'a b\nc\nd'
mystr.split() # 默认分隔符: 泛空格符
['a', 'b', 'c', 'd']

delim = 'NI'
delim.join(['aaa', 'bbb', 'ccc']) # 连接子字符串列表
'aaaNIbbbNIccc'

' '.join(['A', 'dead', 'parrot']) # 在其中添加空格符
chars
'A dead parrot'

chars = list('Lorreta') # 转换为字符组成的列表
chars
['L' , 'o', 'r', 'r', 'e', 't', 'a']
chars.append('!')
''.join(chars) # 生成字符串: 分隔符为空
'Lorreta!'

浙西额调用其实格外有用,例如,对于一行以制表符分隔的多列数据,我们用一次split调用即可将其解析为多个列,实际上,我们可以组成splitjoin来模拟前面介绍的replace函数:

1
2
3
mystr = 'xxaaxxaa'
'SPAM'.join(mystr.split('aa')) # str.replace
'xxSPAMxxSPAM'

Python不会自动将字符串转换为数字,反之亦然,如果要实现两种转换的任意一种,需要手动完成:

1
2
3
4
5
6
7
8
9
10
11
int("42"), eval("42")			# 字符串转换为整型
(42, 42)

str(42) , repr(42) # 整型转换为字符串
('42', '42')

("%d" % 42), '{:d}.format(42)' # 分别借助格式化表达式和方法
('42', '42')

"42" + str(1), int("42") + 1 # 分别为连接和加法
('421', 43)

上面最后一行命令中, 第一个表达式出发字符串连接(因为两边都是字符串) , 而第二个表达式触发加法运算(因为两个对象都是数字).Python并不会嘉定你需要数字还是字符串,然后自行完成转换.Python的第一条指导原则使尽可能避免不必要的神器操作,以及猜测用户行为的诱惑.

Python 3.X中的其他字符串概念: Unicode和字节

Python3.X的字符串功能很丰富,str对象类型, 具有一定序列的字符(从术语来讲就是作为Unicode的”代码单元”出现的Unicode”代码点”),它既代表ASCII码,又代表了更广泛的Unicode文本,并且可以根据需求手动或自动地处理文件传输时的编码与解码.字符串常出现在引号中(如’abc’),而对于非ASCII文本,有多种特殊语法来进行编码(如‘\xc4\xe8’,‘\u00c4\u00e8’)。

Python3.x中添加了两个字符串类型,他们足以支持绝大多数str字符串操作:bytes,用来表示8位二进制数据的短整型序列:bytearray,字节的一个可更改的变异形式。一般来说,你会因为字符串左侧引号前面的字符“b” 而明白自己处理的是字节。3.X中的文件也采取了类似的区分,在文本模式下使用str类型(它也处理Unicode的编码和换行符转换),在二进制模式下使用bytes(在字节序列和文件之间转移时不会改变字节)。

Unicode文本多用于国际化的应用程序中,此外许多针对二进制的Python工具现在也可以处理字节字符串。比如open函数,还有os.listdiros.walk工具。即使是处理简单的目录工具,有时也必须小心文件内容和名称中的Unicode。此外,对象pickle和二进制数据解析等现在都已经成为面向字节的工具。

文件操作基础知识

除了处理字符串,文件对象属于Python语言的核心部分,下面这些调用分别实现了:


实现 调用 注释
文件内容加载为字符串 open(‘file’).read() 将整个文件读取为字符串
固定大小的字节集合加载为字符串 open(‘file’).read(N) 将后面N个字节读取为字符串
文件的内容加载为单行字符串组成的列表 open(‘file’).readlines() 将文件读取为单行字符串组成的列表
文件的下一行加载为字符串 open(‘file’).readline() 跨过‘\n’读取下一行

也可以在Python里对shell命令使用这些调用来读取其输出。文件对象还有用于发送字符串到相关文件的write方法。在Python中,生成输出文件再将它读取回来一如反正。

1
2
3
4
5
6
7
8
9
file = open('spam.txt', 'w') 			# 创建文件 spam.txt
file.write(('spam' * 5) + '\n') # 写入文本:返回所写入的#个字符
21
file.close()

file = open('spam.txt') # 或者用open('spam.txt).read
text = file.read() # 读取为字符串
text
'spamspamspamspamspam\n'

使用程序的两种方式

1
2
if __name__ == '__main__':
import sys # do something

Python每个模块都有一个内置的变量__name__变量,当且仅当文件作为程序运行时,而不是作为库导入时,Python会将这个变量设备__main__字符串。因此,当这个脚本代码作为顶层程序运行时,文件最后几行会自动执行,单在其他地方导入时则不会执行,这个技巧提醒我们要编写可重用的脚本代码:用函数的形式来编写程序,而不是作为顶层代码,这样可以方便以后的导入和重用。

这里的要点是既可以独立运行,也可以在别处导入并调用其中定义的某个函数。