最流行的脚本语言,最适合爬虫的语言
字符串 find :检测某个⼦串是否包含在这个字符串中,如果在返回这个⼦串开始的位置下标,否则则返回-1
index :检测某个⼦串是否包含在这个字符串中,如果在返回这个⼦串开始的位置下标,否则报异常
1 2 字符串序列.find (⼦串, 开始位置下标, 结束位置下标) 字符串序列.index (⼦串, 开始位置下标, 结束位置下标)
开始和结束位置下标可以省略表示在整个字符串序列中
rfind : 和find()功能相同,但查找⽅向为右侧开始
rindex :和index()功能相同,但查找⽅向为右侧开始
count :返回某个⼦串在字符串中出现的次数
1 2 3 字符串序列.rfind (⼦串, 开始位置下标, 结束位置下标) 字符串序列.rindex (⼦串, 开始位置下标, 结束位置下标) 字符串序列.count (⼦串, 开始位置下标, 结束位置下标)
replace :替换
split :按照指定字符分割字符串
join :⽤⼀个字符或⼦串合并字符串,即是将多个字符串合并为⼀个新的字符串
1 2 3 字符串序列.replace (旧⼦串, 新⼦串, 替换次数) 字符串序列.split (分割字符, num) 字符或⼦串.join (多字符串组成的序列)
capitalize :将字符串第⼀个字符转换成⼤写
title :将字符串每个单词⾸字⺟转换成⼤写
lower :将字符串中⼤写转⼩写
upper :将字符串中⼩写转⼤写
1 2 3 4 字符串.capitalize 字符串.title 字符串.lower 字符串.upper
startswith :检查字符串是否是以指定⼦串开头,是则返回 True,否则返回 False。如果设置开始和结束位置下标,则在指定范围内检查
endswith ::检查字符串是否是以指定⼦串结尾,是则返回 True,否则返回 False。如果设置开始和结束位置下标,则在指定范围内检查
1 2 字符串序列.startswith (⼦串, 开始位置下标, 结束位置下标) 字符串序列.endswith (⼦串, 开始位置下标, 结束位置下标)
开始和结束位置下标可以省略表示在整个字符串序列中
isalpha :如果字符串⾄少有⼀个字符并且所有字符都是字⺟则返回 True, 否则返回 False
isalnum :如果字符串⾄少有⼀个字符并且所有字符都是字⺟或数字则返 回 True,否则返回False
isspace :如果字符串中只包含空⽩,则返回 True,否则返回 False
1 2 3 字符串.isalpha () 字符串.isalnum () 字符串.isspace ()
列表 index :返回指定数据所在位置的下标
1 列表序列.index (数据, 开始位置下标, 结束位置下标)
如果查找的数据不存在则报错
count :统计指定数据在当前列表中出现的次数
len :访问列表⻓度,即列表中数据的个数
1 2 列表.count ("判断的字符串" )len (列表)
in :判断指定数据在某个列表序列,如果在返回True,否则返回False
not in :判断指定数据不在某个列表序列,如果不在返回True,否则返回False
1 2 字符串1 in 列表 字符串1 not in 列表
append :列表结尾追加数据,如果append()追加的数据是⼀个序列,则追加整个序列到列表
extend :列表结尾追加数据,如果数据是⼀个序列,则将这个序列的数据逐⼀添加到列表
1 2 列表.append (数据) 列表.extend ((数据)
列表追加数据的时候,直接在原列表⾥⾯追加了指定数据,即修改了原列表,故列表为可变类型数据
1 2 3 4 5 name_list = ['Tom' , 'Lily' , 'Rose' ] name_list.append(['xiaoming' , 'xiaohong' ])
1 2 3 4 5 name_list = ['Tom' , 'Lily' , 'Rose' ] name_list.extend(['xiaoming' , 'xiaohong' ])
insert :指定位置新增数据
del 删除⽬标
pop :删除指定下标的数据(默认为最后⼀个),并返回该数据
remove :移除列表中某个数据的第⼀个匹配项
clear :清空列表
1 2 3 列表.pop 列表.remove 列表.clear
修改指定下标数据
reverse :逆置
1 2 3 4 5 num_list = [1 , 5 , 2 , 3 , 6 , 8 ] num_list.reverse()
sort :排序
reverse表示排序规则,reverse = True 降序, reverse = False 升序(默认)
1 列表.sort( key =None, reverse =False )
copy :复制
元组 列表可以⼀次性存储多个数据,但是列表中的数据允许更改,元组中的数据不允许修改
定义元组使⽤⼩括号,且逗号隔开各个数据,数据可以是不同的数据类型
如果元组里面有列表,修改列表里面的数据则是⽀持的
1 2 3 4 t1 = (10 , 20 , 30 ) t2 = (10 ,)
下标查找
index :查找某个数据,如果数据存在返回对应的下标,否则报错,语法和列表、字符串的index⽅法相同
count :统计某个数据在当前元组出现的次数
len :统计元组中数据的个数
1 2 3 元组.index (字符串) 元组.count (字符串)len (元组)
字典 字典为可变类型
符号为大括号
数据为键值对 形式出现
各个键值对之间⽤逗号隔开
1 2 3 4 dict1 = {'name' : 'Tom' , 'age' : 20 , 'gender' : '男' } dict2 = {}
新增数据
如果key存在则修改这个key对应的值;如果key不存在则新增此键值对
del() / del :删除字典或删除字典中指定键值对
clear :清空字典
get :获取值
如果当前查找的key不存在则返回第⼆个参数(默认值),如果省略第⼆个参数,则返回None
keys :获取所有的key
values :获取所有的值
items :字典转换为列表套元组
1 2 3 字典.keys 字典.values 字典.items
遍历字典的key和value
1 2 3 4 5 6 7 dict1 = {'name' : 'Tom' , 'age' : 20 , 'gender' : '男' }for key in dict1.keys(): print (key) dict2 = {'name' : 'Tom' , 'age' : 20 , 'gender' : '男' }for value in dict2.values(): print (value)
遍历字典中的元素和键值对
1 2 3 4 5 6 7 dict1 = {'name' : 'Tom' , 'age' : 20 , 'gender' : '男' }for item in dict1.items(): print (item) dict2 = {'name' : 'Tom' , 'age' : 20 , 'gender' : '男' }for key, value in dict2.items(): print (f'{key} = {value} ' )
集合 创建集合使⽤ {} 或 set() , 但是如果要创建空集合只能使用 set() ,因为 {} ⽤来创建空字典
集合可以去掉重复数据
集合数据是无序 的,故不⽀持下标
add :增加数据
因为集合有去重功能,所以,当向集合内追加的数据是当前集合已有数据的话,则不进行任何操作
update :追加的数据是序列
1 2 3 4 5 s1 = {10 , 20 } s1.update([100 , 200 ]) s1.update('abc' )print (s1)
remove :删除集合中的指定数据,如果数据不存在则报错
discard :删除集合中的指定数据,如果数据不存在也不会报错
pop :随机删除集合中的某个数据,并返回这个数据
1 2 3 集合.remove 集合.discard 集合.pop
in :判断数据在集合序列
not in :判断数据不在集合序列
公共操作
运算符
描述
支持的容器类型
+
合并
字符串、列表、元组
*
复制
字符串、列表、元组
in
元素是否存在
字符串、列表、元组、字典
not in
元素是否不存在
字符串、列表、元组、字典
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 str1 = 'aa' str2 = 'bb' str3 = str1 + str2print (str3) list1 = [1 , 2 ] list2 = [10 , 20 ] list3 = list1 + list2print (list3) t1 = (1 , 2 ) t2 = (10 , 20 ) t3 = t1 + t2print (t3) print ('-' * 10 ) list1 = ['hello' ]print (list1 * 4 ) t1 = ('world' ,)print (t1 * 4 ) print ('a' in 'abcd' ) print ('a' not in 'abcd' ) list1 = ['a' , 'b' , 'c' , 'd' ]print ('a' in list1) print ('a' not in list1) t1 = ('a' , 'b' , 'c' , 'd' )print ('aa' in t1) print ('aa' not in t1)
函数
描述
len()
计算容器中元素个数
del 或 del()
删除
max()
返回容器中元素最大值
min()
返回容器中元素最小值
range(start, end, step)
生成从start到end的数字,步长为 step,供for循环使用
enumerate()
函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中
len() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 str1 = 'abcdefg' print (len (str1)) list1 = [10 , 20 , 30 , 40 ]print (len (list1)) t1 = (10 , 20 , 30 , 40 , 50 )print (len (t1)) s1 = {10 , 20 , 30 }print (len (s1)) dict1 = {'name' : 'Rose' , 'age' : 18 }print (len (dict1))
del
1 2 3 4 5 6 7 8 9 str1 = 'abcdefg' del str1print (str1) list1 = [10 , 20 , 30 , 40 ]del (list1[0 ])print (list1)
max()和min() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 str1 = 'abcdefg' print (max (str1)) list1 = [10 , 20 , 30 , 40 ]print (max (list1)) str1 = 'abcdefg' print (min (str1)) list1 = [10 , 20 , 30 , 40 ]print (min (list1))
range()
range()生成的序列不包含end数字
1 2 3 4 5 6 7 8 9 10 11 for i in range (1 , 10 , 1 ): print (i)for i in range (1 , 10 , 2 ): print (i)for i in range (10 ): print (i)
enumerate()
start参数用来设置遍历数据的下标的起始值,默认为0
1 enumerate (可遍历对象, start=0 )
1 2 3 4 5 6 7 list1 = ['a' , 'b' , 'c' , 'd' , 'e' ]for i in enumerate (list1): print (i)for index, char in enumerate (list1, start=1 ): print (f'下标是{index} , 对应的字符是{char} ' )
tuple() 将某个序列转换成元组
1 2 3 4 5 list1 = [10 , 20 , 30 , 40 , 50 , 20 ] s1 = {100 , 200 , 300 , 400 , 500 }print (tuple (list1))print (tuple (s1))
list() 将某个序列转换成列表
1 2 3 4 5 t1 = ('a' , 'b' , 'c' , 'd' , 'e' ) s1 = {100 , 200 , 300 , 400 , 500 }print (list (t1))print (list (s1))
set() 将某个序列转换成集合
集合可以快速完成列表去重,集合不支持下标
1 2 3 4 5 list1 = [10 , 20 , 30 , 40 , 50 , 20 ] t1 = ('a' , 'b' , 'c' , 'd' , 'e' )print (set (list1))print (set (t1))
推导式 1 2 3 4 5 6 7 8 [xx for xx in range ()] {xx1: xx2 for ... in ...} {xx for xx in ...}
列表推导式 1 list1 = [i for i in range (10 )]
1 2 3 4 5 list1 = [i for i in range (0 , 10 , 2 )] list1 = [i for i in range (10 ) if i % 2 == 0 ]
字典推导式 1 2 3 dict1 = {i: i**2 for i in range (1 , 5 )}print (dict1)
1 2 3 4 5 6 7 8 9 10 11 12 13 list1 = ['name' , 'age' , 'gender' ] list2 = ['Tom' , 20 , 'man' ] dict1 = {list1[i]: list2[i] for i in range (len (list1))}print (dict1) counts = {'MBP' : 268 , 'HP' : 125 , 'DELL' : 201 , 'Lenovo' : 199 , 'acer' : 99 } count1 = {key: value for key, value in counts.items() if value >= 200 }print (count1)
集合推导式 1 2 3 4 list1 = [1 , 1 , 2 ] set1 = {i ** 2 for i in list1}print (set1)
拆包和交换变量值 元组 1 2 3 4 5 6 7 def return_num (): return 100 , 200 num1, num2 = return_num()print (num1) print (num2)
字典 1 2 3 4 5 6 7 8 9 dict1 = {'name' : 'TOM' , 'age' : 18 } a, b = dict1print (a) print (b) print (dict1[a]) print (dict1[b])
函数 定义函数 在Python中,函数必须先定义后使⽤
局部变量是定义在函数体内 的变量,即只在函数体内部⽣效
全局变量是定义在函数体外 的变量,在全局有效
1 2 3 4 5 def 函数名 (参数 ): 代码1 代码2 ...... return 值
函数参数 位置参数 调用函数时根据函数定义的参数位置来传递参数
传递和定义参数的顺序及个数必须一致
1 2 3 4 5 def user_info (name, age, gender ): print (f'您的名字是{name} , 年龄是{age} , 性别是{gender} ' ) user_info('TOM' , 20 , '男' )
关键字参数 函数调用,通过“键=值”形式加以指定。可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求
1 2 3 4 5 6 def user_info (name, age, gender ): print (f'您的名字是{name} , 年龄是{age} , 性别是{gender} ' ) user_info('Rose' , age=20 , gender='女' ) user_info('小明' , gender='男' , age=16 )
缺省参数 缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值
所有位置参数必须出现在默认参数前,包括函数定义和调用 函数调用时,如果为缺省参数传值则修改默认参数值;否则使用这个默认值
1 2 3 4 5 6 def user_info (name, age, gender='男' ): print (f'您的名字是{name} , 年龄是{age} , 性别是{gender} ' ) user_info('TOM' , 20 ) user_info('Rose' , 18 , '女' )
不定长参数 不定长参数也叫可变参数。用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。此时,可用包裹(packing)位置参数,或者包裹关键字参数,来进行参数传递,会显得非常方便
传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是包裹位置传递
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 def user_info (*args ): print (args) user_info('TOM' ) user_info('TOM' , 18 )def user_info (**kwargs ): print (kwargs) user_info(name='TOM' , age=18 , id =110 )
lambda 基础 lambda表达式的参数可有可无 ,函数的参数在lambda表达式中完全适用
lambda表达式能接收任何数量的参数但只能返回一个表达式的值
1 2 3 4 5 6 7 8 9 def add (a, b ): return a + b result = add(1 , 2 ) result = (lambda a, b: a + b)(1 , 2 )
参数形式 无参数 1 2 fn1 = lambda : 100 print (fn1())
一个参数 1 2 fn1 = lambda a: aprint (fn1('hello world' ))
默认参数 1 2 fn1 = lambda a, b, c=100 : a + b + cprint (fn1(10 , 20 ))
可变参数:*args 1 2 fn1 = lambda *args: argsprint (fn1(10 , 20 , 30 ))
这里的可变参数传入到lambda之后,返回值为元组
可变参数:**kwargs 1 2 fn1 = lambda **kwargs: kwargsprint (fn1(name='python' , age=20 ))
高阶函数 把函数作为参数传入 ,这样的函数称为高阶函数,高阶函数是函数式编程的体现。函数式编程就是指这种高度抽象的编程范式
map() map(func, lst),将传入的函数变量func作用到lst变量的每个元素中,并将结果组成新的列表(Python2)/迭代器(Python3)返回
1 2 3 4 5 6 7 8 9 10 list1 = [1 , 2 , 3 , 4 , 5 ]def func (x ): return x ** 2 result = map (func, list1)print (result) print (list (result))
reduce() reduce(func,lst),其中func必须有两个参数。每次func计算的结果继续和序列的下一个元素做累积计算。
reduce()传入的参数func必须接收2个参数
1 2 3 4 5 6 7 8 9 10 11 import functools list1 = [1 , 2 , 3 , 4 , 5 ]def func (a, b ): return a + b result = functools.reduce(func, list1)print (result)
filter() filter(func, lst)函数用于过滤序列, 过滤掉不符合条件的元素, 返回一个 filter 对象。如果要转换为列表, 可以使用 list() 来转换
1 2 3 4 5 6 7 8 9 list1 = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ]def func (x ): return x % 2 == 0 result = filter (func, list1)print (result) print (list (result))
文件操作 打开 在python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件
name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径) mode:设置打开文件的模式(访问模式):只读、写入、追加等
打开文件模式
模式
描述
r
以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb
以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
r+
打开一个文件用于读写。文件指针将会放在文件的开头。
rb+
以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
w
打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb
以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
w+
打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb+
以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
a
打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab
以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+
打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab+
以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。
写入
1 2 3 4 5 6 7 8 f = open ('test.txt' , 'w' ) f.write('hello world' ) f.close()
w
和a
模式:如果文件不存在则创建该文件;如果文件存在,w
模式先清空再写入,a
模式直接末尾追加r
模式:如果文件不存在则报错
读取
num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据
readlines :可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素
1 2 3 4 5 6 7 8 f = open ('test.txt' ) content = f.readlines()print (content) f.close()
readline :一次读取一行内容
1 2 3 4 5 6 7 8 9 10 f = open ('test.txt' ) content = f.readline()print (f'第一行:{content} ' ) content = f.readline()print (f'第二行:{content} ' ) f.close()
文件备份 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 old_name = input ('请输入您要备份的文件名:' ) index = old_name.rfind('.' )if index > 0 : postfix = old_name[index:] new_name = old_name[:index] + '[备份]' + postfix old_f = open (old_name, 'rb' ) new_f = open (new_name, 'wb' )while True : con = old_f.read(1024 ) if len (con) == 0 : break new_f.write(con) old_f.close() new_f.close()
文件和文件夹的操作 在Python中文件和文件夹的操作要借助os模块里面的相关功能,具体步骤
导入os
模块
使用os
模块相关功能
文件重命名
删除文件
创建文件夹
删除文件夹
获取当前目录
改变默认目录
获取目录列表
类和对象 定义类
不由任意内置类型派生出的类,称之为经典类
创建对象
创建对象的过程也叫实例化对象
1 2 3 4 5 6 7 8 haier1 = Washer()print (haier1) haier1.wash()
self self指的是调用该函数的对象
打印对象和self得到的结果是一致的,都是当前对象的内存中存储地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Washer (): def wash (self ): print ('我会洗衣服' ) print (self) haier1 = Washer()print (haier1) haier1.wash() haier2 = Washer()print (haier2)
魔法方法 init ()__init__()
方法的作用:初始化对象
__init__()
方法,在创建一个对象时默认被调用 ,不需要手动调用__init__(self)
中的self参数,不需要开发者传递 ,python解释器会自动把当前的对象引用传递过去
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Washer (): def __init__ (self ): self.width = 500 self.height = 800 def print_info (self ): print (f'宽度是{self.width} , 高度是{self.height} ' )class Washer2 (): def __init__ (self,width,height ): self.width = width self.height = height def print_info (self ): print (f'宽度是{self.width} , 高度是{self.height} ' ) haier1 = Washer() haier1.print_info() haier2 = Washer2(100 ,200 )
str ()当使用print输出对象的时候,默认打印对象的内存地址。如果类定义了__str__
方法,那么就会打印从在这个方法中 return 的数据
1 2 3 4 5 6 7 8 9 10 11 12 class Washer (): def __init__ (self, width, height ): self.width = width self.height = height def __str__ (self ): return '打印' haier1 = Washer(10 , 20 )print (haier1)
del ()当删除对象时,python解释器也会默认调用__del__()
方法
1 2 3 4 5 6 7 8 9 10 11 12 13 class Washer (): def __init__ (self, width, height ): self.width = width self.height = height def __del__ (self ): print (f'{self} 对象已经被删除' ) haier1 = Washer(10 , 20 )del haier1
面向对象三大特性 封装
将属性和方法书写到类的里面的操作即为封装
封装可以为属性和方法添加私有权限
继承
子类默认继承父类的所有属性和方法
子类可以重写父类属性和方法
多态
继承 继承的特点
子类默认拥有父类的所有属性和方法
子类重写父类同名方法和属性
子类调用父类同名方法和属性
super()方法快速调用父类方法
私有权限
1 2 3 4 5 6 7 class 类名 (): __属性名 = 值def __函数名 (self ): 代码
多态 多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承)
定义:多态是一种使用对象的方式,子类重写父类方法,调用不同子类对象的相同父类方法 ,可以产生不同的执行结果
实现步骤:
定义父类,并提供公共方法
定义子类,并重写父类方法
传递子类对象给调用者,可以看到不同子类执行效果不同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Dog (object ): def work (self ): print ('指哪打哪...' )class ArmyDog (Dog ): def work (self ): print ('追击敌人...' )class DrugDog (Dog ): def work (self ): print ('追查毒品...' )class Person (object ): def work_with_dog (self, dog ): dog.work() ad = ArmyDog() dd = DrugDog() daqiu = Person() daqiu.work_with_dog(ad) daqiu.work_with_dog(dd)
类方法 1 2 3 @classmethod def xx (): 代码
静态方法 1 2 3 @staticmethod def xx (): 代码
异常和导包 异常 语法 1 2 3 4 5 6 7 8 try : 可能发生异常的代码except : 如果出现异常执行的代码else : 没有异常执行的代码finally : 无论是否异常都要执行的代码
捕获异常 1 2 3 4 5 except 异常类型: 代码except 异常类型 as xx: 代码
自定义异常 1 2 3 4 5 6 7 8 9 10 11 12 13 14 class 异常类类名 (Exception ): 代码 def __str__ (self ): return ...raise 异常类名()except Exception...
模块 导入模块方法 1 2 3 4 5 import 模块名from 模块名 import 目标from 模块名 import *
导入包 1 2 3 import 包名.模块名from 包名 import *
__all__ = []
:允许导入的模块或功能列表
进程和线程 多进程
Process([group [, target [, name [, args [, kwargs]]]]])
group:指定进程组,目前只能使用None
target:执行的目标任务名
name:进程名字
args:以元组方式给执行任务传参
kwargs:以字典方式给执行任务传参
Process创建的实例对象的常用方法
start():启动子进程实例(创建子进程)
join():等待子进程执行结束
terminate():不管任务是否完成,立即终止子进程
Process创建的实例对象的常用属性:
name:当前进程的别名,默认为Process-N,N为从1开始递增的整数
1 2 3 import os os.getpid() os.getppid()
简单使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import multiprocessingimport timedef dance (): for i in range (5 ): print ("跳舞中..." ) time.sleep(0.2 )def sing (): for i in range (5 ): print ("唱歌中..." ) time.sleep(0.2 )if __name__ == '__main__' : dance_process = multiprocessing.Process(target=dance, name="myprocess1" ) sing_process = multiprocessing.Process(target=sing) dance_process.start() sing_process.start()
注意 进程之间不共享全局变量
主进程会等待所有的子进程执行结束再结束
多线程
Thread([group [, target [, name [, args [, kwargs]]]]])
group: 线程组,目前只能使用None
target: 执行的目标任务名
args: 以元组的方式给执行任务传参
kwargs: 以字典方式给执行任务传参
name: 线程名,一般不用设置
启动线程使用start方法
简单使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 import threadingimport timedef sing (): for i in range (3 ): print ("正在唱歌...%d" % i) time.sleep(1 )def dance (): for i in range (3 ): print ("正在跳舞...%d" % i) time.sleep(1 )if __name__ == '__main__' : sing_thread = threading.Thread(target=sing) dance_thread = threading.Thread(target=dance) sing_thread.start() dance_thread.start()
注意 线程之间执行是无序的
主线程会等待所有的子线程执行结束再结束
线程之间共享全局变量
线程之间共享全局变量数据出现错误问题
闭包和装饰器 闭包 在函数嵌套的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,我们把这个使用外部函数变量的内部函数称为闭包
闭包构成的条件
在函数嵌套(函数里面再定义函数)的前提下
内部函数使用了外部函数的变量(还包括外部函数的参数)
外部函数返回了内部函数
闭包的作用:闭包可以保存外部函数内的变量,不会随着外部函数调用完而销毁
1 2 3 4 5 6 7 8 9 def test1 (a ): b = 10 def test2 (): print (a, b) return test2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 def func_out (num1 ): def func_inner (num2 ): result = num1 + num2 print ("结果是:" , result) return func_inner f = func_out(1 ) f(2 ) f(3 )''' 结果 结果是: 3 结果是: 4 '''
装饰器 给已有函数增加额外功能的函数,它本质上就是一个闭包函数
功能
不修改已有函数的源代码
不修改已有函数的调用方式
给已有函数增加额外的功能
1 2 3 4 5 6 def decorator (fn ): def inner (): '''执行函数之前''' fn() '''执行函数之后''' return inner
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 def check (fn ): def inner (): print ("请先登录...." ) fn() return innerdef comment (): print ("发表评论" ) comment = check(comment) comment()''' 结果 请先登录.... 发表评论 '''
语法糖写法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def check (fn ): print ("装饰器函数执行了" ) def inner (): print ("请先登录...." ) fn() return inner@check def comment (): print ("发表评论" ) comment()
多个装饰器使用 多个装饰器的装饰过程是: 离函数最近的装饰器先装饰,然后外面的装饰器再进行装饰,由内到外的装饰过程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 def make_div (func ): """对被装饰的函数的返回值 div标签""" def inner (*args, **kwargs ): return "<div>" + func() + "</div>" return innerdef make_p (func ): """对被装饰的函数的返回值 p标签""" def inner (*args, **kwargs ): return "<p>" + func() + "</p>" return inner@make_div @make_p def content (): return "人生苦短" result = content()print (result)
带有参数的装饰器 装饰器只能接收一个参数,并且还是函数类型
在装饰器外面再包裹上一个函数,让最外面的函数接收参数,返回的是装饰器,因为@符号后面必须是装饰器实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 def logging (flag ): def decorator (fn ): def inner (num1, num2 ): if flag == "+" : print ("--正在努力加法计算--" ) elif flag == "-" : print ("--正在努力减法计算--" ) result = fn(num1, num2) return result return inner return decorator@logging("+" ) def add (a, b ): result = a + b return result@logging("-" ) def sub (a, b ): result = a - b return result result = add(1 , 2 )print (result) result = sub(1 , 2 )print (result)
相关文章
Python爬虫
Mongodb和Python交互
Python反爬解决方案
Scrapy爬虫
Python打包可执行文件