admin 管理员组文章数量: 1184232
【AI
这一篇博文是【 AI学习路线图】系列文章的其中一篇,点击查看目录:AI学习完整路线图
一、 概述
这个博文的内容都是基于Python3.6.2版本,由于Python3和Python3有很多不同,所以这个笔记中的代码可能在Python2下会无法运行。
Python是一种解释型、面向对象、动态数据类型的高级程序设计语言,是由Guido van Rossum于1989年底发明的。
二、 语法知识
1、 数据类型
(1) 标准数据类型
Python中有6个标准的数据类型:
- Number
Python3中Number有int,float,bool,complex(复数),Python3中只有一种int整数类型,没有Long。 - String
String用单引号或者双引号引起来的。 - List
List是Python里使用最频繁的类型,用[]括起来。 - Tuple
Tuple是元组,与List类似,但是Tuple中的元素不可以修改,用()括起来。 - Sets
Sets是一个无序不重复的元素集合,使用{}或者set()括起来。 - Dictionary
字典中的元素是通过键来存取的。
(2) 查询类型
可以用type()查看对象的类型。
if __name__ == '__main__':s = 1print(type(s))s = 'a'print(type(s))
输出:
<class 'int'>
<class 'str'>
也可以用isinstance判断类型:
if __name__ == '__main__':s = 1 print(isinstance(s,int))s = 'a' print(isinstance(s,str))
输出:
True
True
type和isinstance的区别是ininstance认为子类是一种父类类型,type认为不相同。
2、 运算符
(1) 算术运算符
假设变量a为10,b为21
| 运算符 | 描述 | 实例 |
|---|---|---|
| + | 加 - 两个对象相加 | a + b 输出结果 31 |
| - | 减 - 得到负数或是一个数减去另一个数 | a - b 输出结果 -11 |
| * | 乘 - 两个数相乘或是返回一个被重复若干次的字符串 | a * b 输出结果 210 |
| / | 除 - x 除以 y | b / a 输出结果 2.1 |
| % | 取模 - 返回除法的余数 | b % a 输出结果 1 |
| ** | 幂 - 返回x的y次幂 | a**b 为10的21次方 |
| // | 取整除 - 返回商的整数部分 | 9//2 输出结果 4 , 9.0//2.0 输出结果 4.0 |
(2) 比较运算符
假设变量a为10,b为21
| 运算符 | 描述 | 实例 |
|---|---|---|
| == | 等于 - 比较对象是否相等 | (a == b) 返回 False。 |
| != | 不等于 - 比较两个对象是否不相等 | (a != b) 返回 True。 |
| > | 大于 - 返回x是否大于y | (a > b) 返回 False。 |
| < | 小于 - 返回x是否小于y。所有比较运算符返回1表示真,返回0表示假。这分别与特殊的变量True和False等价。注意,这些变量名的大写。 | (a < b) 返回 True。 |
= | 大于等于 - 返回x是否大于等于y。 | (a >= b) 返回 False。 |
| <= | 小于等于 - 返回x是否小于等于y。 | (a <= b) 返回 True。 |
(3) 赋值运算符
假设变量a为10,b为21
| 运算符 | 描述 | 实例 |
|---|---|---|
| = | 简单的赋值运算符 | c = a + b 将 a + b 的运算结果赋值为 c |
| += | 加法赋值运算符 | c += a 等效于 c = c + a |
| -= | 减法赋值运算符 | c -= a 等效于 c = c - a |
| *= | 乘法赋值运算符 | c *= a 等效于 c = c * a |
| /= | 除法赋值运算符 | c /= a 等效于 c = c / a |
| %= | 取模赋值运算符 | c %= a 等效于 c = c % a |
| **= | 幂赋值运算符 | c **= a 等效于 c = c ** a |
| //= | 取整除赋值运算符 | c //= a 等效于 c = c // a |
(4) 逻辑运算符
假设变量a为10,b为21
| 运算符 | 逻辑表达式 | 描述 | 实例 |
|---|---|---|---|
| and | x and y | 布尔”与” - 如果 x 为 False,x and y 返回 False,否则它返回 y 的计算值。 | (a and b) 返回 20。 |
| or | x or y | 布尔”或” - 如果 x 是 True,它返回 x 的值,否则它返回 y 的计算值。 | (a or b) 返回 10。 |
| not | not x | 布尔”非” - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。 | not(a and b) 返回 False |
(5) 位运算符
变量 a 为 60,b 为 13二进制格式如下
a = 0011 1100
b = 0000 1101
| 运算符 | 描述 | 实例 |
|---|---|---|
| & | 按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 | (a & b) 输出结果 12 ,二进制解释: 0000 1100 |
| 按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。 | ||
| ^ | 按位异或运算符:当两对应的二进位相异时,结果为1 | (a ^ b) 输出结果 49 ,二进制解释: 0011 0001 |
| ~ | 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1。 ~x 类似于 -x-1 | (~a ) 输出结果 -61 ,二进制解释: 1100 0011, 在一个有符号二进制数的补码形式。 |
| << | 左移动运算符:运算数的各二进位全部左移若干位,由”<<”右边的数指定移动的位数,高位丢弃,低位补0。 | a << 2 输出结果 240 ,二进制解释: 1111 0000 |
> | 右移动运算符:把”>>”左边的运算数的各二进位全部右移若干位,”>>”右边的数指定移动的位数 | a >> 2 输出结果 15 ,二进制解释: 0000 1111 |
(6) 成员运算符
| 运算符 | 描述 | 实例 |
|---|---|---|
| in | 如果在指定的序列中找到值返回 True,否则返回 False。 | x 在 y 序列中 , 如果 x 在 y 序列中返回 True。 |
| not in | 如果在指定的序列中没有找到值返回 True,否则返回 False。 | x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。 |
(7) 身份运算符
| 运算符 | 描述 | 实例 |
|---|---|---|
| is | is 是判断两个标识符是不是引用自一个对象 | x is y , 类似 id(x) == id(y) , 如果引用的是同一个对象则返回 True,否则返回 False |
| is not | is not 是判断两个标识符是不是引用自不同对象 | x is not y , 类似 id(a) != id(b)。如果引用的不是同一个对象则返回结果 True,否则返回 False。 |
(8) 运算符优先级
优先级由高到低为:
| 运算符 | 描述 |
|---|---|
| ** | 指数 (最高优先级) |
| ~ + - | 按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@) |
| * / % // | 乘,除,取模和取整除 |
| 加法减法 |
<< | 右移,左移运算符 |
| & | 位 ‘AND’ |
| ^ | |
| <= < > >= | 比较运算符 |
| <> == != | 等于运算符 |
| = %= /= //= -= += *= **= | 赋值运算符 |
| is is not | 身份运算符 |
| in not in | 成员运算符 |
| not or and | 逻辑运算符 |
3、 条件语句
(1) if语句
简单的if:
list = [2, 5, 1, 9, 3, 7, 11, 14, 18]
for item in list:if item > 5:print(str(item) + " 大于5")
if – else:
list = [2, 5, 1, 9, 3, 7, 11, 14, 18]
for item in list:if item > 5:print(str(item) + " 大于5")else:print(str(item) + " 不大于5")
if-elif-else:
list = [2, 5, 1, 9, 3, 7, 11, 14, 18]
for item in list:if item > 10:print(str(item) + " 大于10")elif item > 5:print(str(item) + " 大于5")else:print(str(item) + " 不大于5")
(2) 是否相等/不等
list = [2, 5, 1, 9, 3, 5, 7, 11, 14, 18]
for item in list:if item == 5:print("第" + str(list.index(item)) + "个是5")elif item != 3:print("第" + str(list.index(item)) + "不是3")
(3) 多个条件 and/or
list = [2, 5, 1, 9, 3, 5, 7, 11, 14, 18]
for item in list:if item > 5 and item < 10:print(item)
list = [2, 5, 1, 9, 3, 5, 7, 11, 14, 18]
for item in list:if item < 5 or item > 10:print(item)
(4) 是否包含/不包含在列表中
list = [2, 5, 1, 9, 3, 5, 7, 11, 14, 18]
if 4 in list:print("4包含在列表中")
else:print("no 4")
list = [2, 5, 1, 9, 3, 5, 7, 11, 14, 18]
if 4 not in list:print("no 4")
(5) 确定列表是否为空
list = [2, 5, 1, 9, 3, 7, 11, 14, 18]
if list:for item in list:print(item)
4、 循环语句
(1) 使用while
s=0
n=1;
while n<=10:s=s+nn=n+1
print(s)
(2) for循环
if __name__ == '__main__':for i in range(1,9):print(i)list=['a',4,"g",True]for i in list:print(i)
(3) break
# 如果平方大于100就退出
for item in range(1, 100):if (item ** 2 > 100):breakelse:print(item)
print("=======================")
(4) continue
# 如果是偶数就进入下一个循环
for item in range(1, 10):if (item ** 2 % 2 == 0):continueelse:print(item)
5、 函数
(1) 定义函数
def hello(name, msg):'''打印信息'''print(name, ',', msg)
def表明要定义一个函数,hello是函数名称,name和msg是两个形参,三个单引号引起来的内容是这个函数的说明,用于生成说明文档。函数体是一句话用打印内容。
(2) 关键字实参
def hello(name, msg):'''打印信息'''print(name, ',', msg)if __name__ == "__main__":#顺序实参,是根据参数顺序赋值给函数形参hello("chybin", "hello")#关键字实参是指定形参的关键字,所以顺序就无所谓了hello(msg="hello!", name="chybin")
(3) 函数形参指定默认值
def hello(name, msg='你好'):'''打印信息'''print(name, ',', msg)if __name__ == "__main__":hello("chybin")hello("chybin","hello")
指定了msg的默认值,当调用函数时,可以不传msg参数,就是用定义的默认值,如果指定了参数,就使用指定的参数。
(4) 返回字典
当函数的返回值有多个时,可以封装为一个字典返回。
(5) 不定长参数
def mylist(*list):r = []for item in list:r.append(item * 2)return rif __name__ == "__main__":r = mylist(4, 6, 2, 9, 10)print(r)r = mylist(55,66)print(r)
参数前面有个*,表明参数个数不确定,就是定一个一list的列表,接收传递的参数。
(6) 不定长的关键字参数
def userinfo(name, age, **otherInfo):info = {}info['name'] = nameinfo['age'] = agefor key, val in otherInfo.items():info[key] = valprint(info)if __name__ == '__main__':userinfo('jock', 20, province='河北', city='廊坊')
(7) 函数嵌套
# 函数嵌套
def fun1():def fun2():print("function2")print("fun1")return fun2if __name__ == '__main__':obj = fun1()print('-------')obj()
函数中可以再定义函数,外层函数可以将内层函数做为一个返回值返回,调用方可以对返回的函数进行执行操作。
(8) 函数闭包
# 函数闭包
def f0(x):def f1(y):print(x + y)return f1if __name__ == '__main__':obj = f0(10)obj(20)
(9) 装饰器
# 定义一个装饰器方法,log可以装饰其他方法
def log(func):# 定义一个内部方法,将这个方法做为装饰器的返回值,装饰后会执行它def wrap(*args, **kwargs):# 装饰器内做的工作print("添加日志开始")# 其中一项工作是执行被装饰的方法r = func(*args, **kwargs)print("添加日志结束")# 将被装饰的方法返回值返回装饰器return rreturn wrap# 用@来表示装饰器,加载被装饰方法的头上
@log
def delete(name):print("删除" + name + "操作")return "ok"if __name__ == '__main__':#执行被装饰的方法时,会先执行装饰器,由装饰器来执行delete方法。r = delete("jock")print(r)
带参数的装饰器:# 定义一个装饰器方法,log2可以装饰其他方法
def log2(i):def wrap1(func):# 定义一个内部方法,将这个方法做为装饰器的返回值,装饰后会执行它def wrap(*args, **kwargs):# 装饰器内做的工作print("添加日志开始")# 其中一项工作是执行被装饰的方法r = func(*args, **kwargs)print("添加日志结束")print(i)# 将被装饰的方法返回值返回装饰器return rreturn wrapreturn wrap1# 用@来表示装饰器,加载被装饰方法的头上
@log2(10)
def delete(name):print("删除" + name + "操作")return "ok"if __name__ == '__main__':# 执行被装饰的方法时,会先执行装饰器,由装饰器来执行delete方法。r = delete("jock")print(r)
(10) 迭代器
import itertoolsa = [1, 2, 3]
b = ['a', 'b', 'c']
x = range(1, 5)
com1 = itertoolsbinations(x, 3) # 排列
com2 = itertools.permutations(x, 3) # 组合
com3 = itertools.product(a, b) # 笛卡尔积
com4 = itertools.chain(com1, com2, com3) # 链接print("-----com1-----")
for i in com1:print(i)
com1 = itertoolsbinations(x, 3) # 排列print("---com2----")
for i in com2:print(i)
print("--com3------")
for i in com3:print(i)
print("====com4======")
for m in com4:print(m)
对上述代码的猜测:
iteertools生成的对象只能被迭代一次,所以第二次对com1、com2、com3迭代就会发现打印为空。
另外chain链接是对com1、com2、com3的引用的链接,前面对com1进行迭代过后,com4所对应的引用也为空了。
三、 数据结构
1、 列表
有一定顺序排列的元素组成列表,可将任何东西都放入列表中,用[]来表示列表。
(1) 定义列表
mylist=[1,'a',False,9.8]
print(mylist)
(2) 访问列表元素
mylist=[1,'a',False,9.8]
print(mylist[0])
print(mylist[1])
print(mylist[2])
print(mylist[3])
(3) 修改元素
mylist=[1,'a',False,9.8]
mylist[0]='b'
print(mylist)
输出:
['b', 'a', False, 9.8]
(4) 追加元素
mylist=[1,'a',False,9.8]
mylist.append(0)
print(mylist)
输出:
[1, 'a', False, 9.8, 0]
(5) 插入元素
mylist=[1,'a',False,9.8]
mylist.insert(1,'88')
print(mylist)
输出:
[1, '88', 'a', False, 9.8]
(6) 删除元素
mylist=[1,'a',False,9.8]
del mylist[3]
print(mylist)
输出:
[1, 'a', False]
(7) 弹出元素
mylist=[1,'a',False,9.8]
f=mylist.pop(0)
print(mylist)
print(f)
mylist.pop()
print(mylist)
mylist.pop()
print(mylist)
输出:
['a', False, 9.8]
['a', False]
['a']
弹出元素是将最后一个或者指定位置的元素删除,删除后还可以得到被删除的元素。
(8) 根据值删除元素
mylist=[1,'a',False,'a',9.8]
mylist.remove('a')
print(mylist)
输出:
[1, False, 'a', 9.8]
根据值删除元素只能删除第一个元素。
(9) 对列表永久排序
mylist=[9,4,1,8,2]
mylist.sort()
print(mylist)
输出:
[1, 2, 4, 8, 9]
mylist=[9,4,1,8,2]
mylist.sort(reverse=True)
print(mylist)
输出:
[9, 8, 4, 2, 1]
永久排序后原来的列表顺序就变了。
(10) 对列表进行临时排序
mylist = [9, 4, 1, 8, 2]
print(sorted(mylist))
print(mylist)
输出:
[1, 2, 4, 8, 9]
[9, 4, 1, 8, 2]
临时排序没有修改原列表的顺序。
(11) 反转列表
mylist = [9, 4, 1, 8, 2]
mylist.reverse();
print(mylist)
输出:
[2, 8, 1, 4, 9]
反转列表是将原列表修改
(12) 读取列表的长度
mylist = [9, 4, 1, 8, 2]
print(len(mylist))
输出:
5
(13) 遍历列表
mylist = [9, 4, 1, 8, 2]
for item in mylist:print(item)
输出:
9
4
1
8
2
(14) 数字列表统计
mylist = [9, 4, 1, 8, 2]
print(min(mylist))
print(max(mylist))
print(sum(mylist))
输出:
1
9
24
(15) 列表解析
result=[val*2 for val in range(1,9)]
print(result)
输出:
[2, 4, 6, 8, 10, 12, 14, 16]
列表解析是对于列表进行逐个计算,得到另外一个列表的过程,
(16) 列表切片
mylist = [9, 4, 1, 8, 2]
print(mylist[1:3])
print(mylist)
输出:
[4, 1]
[9, 4, 1, 8, 2]
切片是将列表中的一部分切出来,要指定开始的索引值和结束的索引值,但是切片不包含结束索引,类似range(1,9),不包括9。
切片是将原列表中一部分切出来,复制到一个新的空间,所以对切片的修改不会影响到原列表。
几种常见的表达:
- arr[start_index: ]:缺省end_index,表示从start_index开始到序列中最后一个对象。
- arr[: end_index]:缺省start_index,表示从序列中第一个对象到end_index-1之间的片段。
- arr[:]:缺省start_index和end_index,表示从第一个对象到最后一个对象的完整片段。
- arr[::step]:缺省start_index和end_index,表示对整个序列按照索引可以被step整除的规则取值。
mylist = [9, 4, 1, 8, 2]# 指定开始,不指定结束,就是从开始切到最后,包括开始索引值
# 结果为[1, 8, 2]
print(mylist[2:])# 不指定开始,从开始切到指定索引值,不包括结束
# 结果为[9, 4]
print(mylist[:2])# 不指定开始和结束,就是全部切下来
# 结果为[9, 4, 1, 8, 2]
print(mylist[:])# 指定步长,索引值能被步长值整除的保留下来
# 结果:[9, 1, 2]
print(mylist[::2])# 结束为负数,最后一个为-1,
# #也可以理解为从后面切下去几个
# 结果[9, 4, 1, 8]
print(mylist[:-1])# 结束为负数,倒数第二个为-2,
# 结果[9, 4, 1]
print(mylist[:-2])# 开始为负数,从倒数第几个切
# 结果:[1, 8, 2]
print(mylist[-3:])
(17) 复制列表
不能通过=赋值的方式复制列表,因为=只是修改复制了对列表的索引,并没有复制值,修改了新的列表,老的列表也会修改。例如:
mylist = [9, 4, 1, 8, 2]
print(mylist)
mylist2 = mylist
mylist2.pop()
print(mylist)
输出:
[9, 4, 1, 8, 2]
[9, 4, 1, 8]
可以通过就列表的全部切片进行复制
mylist = [9, 4, 1, 8, 2]
print(mylist)
mylist2 = mylist[:]
mylist2.pop()
print(mylist)
输出:
[9, 4, 1, 8, 2]
[9, 4, 1, 8, 2]
(18) 判断元素是否在列表中
mylist = [9, 4, 1, 8, 2]
if 4 in mylist:print("exist")
else:print("no")if 4 not in mylist:print("yes")
else:print("no")
输出:
exist
2、 元组
不可变的列表就是元组。
(1) 定义元组
my_tup=(1,2,'3')
定义元组和定义列表一样,但是元组是用圆括号标示。
(2) 遍历元组
my_tup=(1,2,'3')
for tup in my_tup:print(tup)
(3) 修改元组变量
元组的值不可以修改,但是元组变量可以重新赋值进行修改。
my_tup=(1,2,'3')
for tup in my_tup:print(tup)
my_tup=('a','b',True)
print("修改后:")
for tup in my_tup:print(tup)
(4) 访问元组
tup = (1, 2, 3, 4, 5)# 根据索引取值
print(tup[2])# 根据开始结束索引切片
print(tup[1:4])# -1就是倒数第一个
print(tup[2:-1])
(5) 元组运算
| header 表达式 | 结果 | 描述 |
|---|---|---|
| len((1,2,3)) | 3 | 元组长度 |
| (1,2)+(3,)) | (1,2,3) | 元组连接 |
| (‘h’,)*2 | (‘h’,’h’) | 复制元素 |
| 1 in (1,2) | True | 是否存在 |
3、 字典
Python中字典是一系列的键值对,与键关联的值可以是数字、字符串、列表、字典等任何对象。
(1) 定义字典
dict = {'id': 1, 'name': 'Chybin', 'gril_friend_id': [1, 2, 3]}
定义字典用花括号标示。
(2) 访问字典里的值
dict = {'id': 1, 'name': 'Chybin', 'gril_friend_id': [1, 2, 3]}
print(dict["id"])
print(dict["name"])
(3) 添加键值对
字典是一种动态结构,可以随时添加键值对,
dict = {'id': 1, 'name': 'Chybin', 'gril_friend_id': [1, 2, 3]}
dict["x"]=123
dict["y"]="abc"
print(dict)
(4) 修改值
dict = {'id': 1, 'name': 'Chybin', 'gril_friend_id': [1, 2, 3]}
dict["id"]=99
print(dict)
(5) 删除键值对
dict = {'id': 1, 'name': 'Chybin', 'gril_friend_id': [1, 2, 3]}
del dict['name']
print(dict)
(6) 遍历字典
dict = {'id': 1, 'name': 'Chybin', 'gril_friend_id': [1, 2, 3]}
for k, v in dict.items():print("key=" + k + ";value=" + str(v))
(7) 遍历键
dict = {'id': 1, 'name': 'Chybin', 'gril_friend_id': [1, 2, 3]}
for k in dict.keys():print(k)
(8) key排序后输出
dict = {'id': 1, 'name': 'Chybin', 'gril_friend_id': [1, 2, 3]}
for k in sorted(dict.keys()):print(k + ":" + str(dict[k]))
通过sorted对key进行排序
(9) 遍历值
dict = {'id': 1, 'name': 'Chybin', 'gril_friend_id': [1, 2, 3]}
for v in dict.values():print(v)
(10) 字典列表
list=[]
dict = {'id': 1, 'name': 'Chybin', 'gril_friend_id': [1, 2, 3]}
for i in range(1,6):list.append(dict)
print(list)
4、 集合
集合是无序不重复的列表
四、 模块
1、 定义模块
Python中模块是一个python文件,以.py结尾。把相关的代码放入一个模块中,使得程序更加清晰。模块中能定义函数、类、变量等。
定义一个模块,放入文件myprint.py中。
#!/usr/local/bin python3
# coding=utf-8
def printInfo():print(1)print(1.0)print("hello world!")print(True)def jiujiu():i = 1while i <= 9:j = 1while j <= i:print(str(j) + "*" + str(i) + "=" + str(i * j) + " ", end="")j = j + 1print("\r")i = i + 1
2、 导入整个模块
在另外一个py文件中,导入myprint整个模块
import myprintif __name__ == '__main__':# 使用模块名.函数名调用方法
myprint.jiujiu()运行结果如下:
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
3、 导入某个函数
from myprint import jiujiuif __name__ == '__main__':jiujiu()
这个例子只是导入模块中的一个函数,调用时不用指定模块名,直接使用函数名。
4、 导入所有的函数
from myprint import *if __name__ == '__main__':jiujiu()
这个是将所有的函数都导入到当前模块中,对于其他人的大型模块一定要慎用,因为可能会造成名字冲突。
5、 as指定模块别名
import myprint as mpif __name__ == '__main__':mp.jiujiu()
当模块名字比较长时,可以指定一个别名,之后用别名调用。
五、 进程与线程
Python中有一个multiprocessing模块来实现多进程。
1、 多进程
(1) Process类
使用Process类来创建进程类。
构造方法为:Process([group [,target [, name [, args [, kwargs]]]])
- target参数是指调用的对象
- name是创建的类的别名
- args是向运行的对象传递参数
常用方法有:
is_alive()、join([timeout])、run()、start()。
- is_alive() 进程是否是存活状态
- join([timeout]) 可以在主进程中等待子进程执行完毕后再往下执行,通常用于进程同步
- run() 执行进程中的代码,如果执行了target就执行targeet,没有指定就默认执行对象中的run方法。
- start() 启动进程
常用属性有:
daemon、name、pid
实例1:进程为执行函数
#-*-coding:utf-8
import multiprocessing
import time#创建函数并将其作为单个进程
def worker(interval): #interval间歇,间隔n = 5 #进程数while n > 0:print("The time is {0}".format(time.ctime())) #初始化时间time.sleep(interval) #睡眠时间n -= 1 #递减if __name__ == "__main__":
#创建一个进程,target:调用对象,args:传参数到对象,此处表示睡眠值p = multiprocessing.Process(target=worker, args=(3,)) p.start() #开启进程print("p.pid:", p.pid) #进程号print("p.name:", p.name) #别名print("p.is_alive:", p.is_alive()) #进程是否存活
实例2: 函数多个进程:
# -*-coding:utf-8
import multiprocessing
import time# 创建函数并将其作为多个进程
def worker_1(interval):time.sleep(interval)print("worker_1")print("end worker_1")def worker_2(interval):time.sleep(interval)print("worker_2")print("end worker_2")def worker_3(interval):time.sleep(interval)print("worker_3")print("end worker_3")if __name__ == "__main__":# 定义三个进程对象p1 = multiprocessing.Process(target=worker_1, args=(2,))p2 = multiprocessing.Process(target=worker_2, args=(3,))p3 = multiprocessing.Process(target=worker_3, args=(4,))# 启动三个进程p1.start()p2.start()p3.start()# 打印当前CPU逻辑核的数量print("The number of CPU is:" + str(multiprocessing.cpu_count()))for p in multiprocessing.active_children():print("child p.name:" + p.name + "\tp.id" + str(p.pid))p1.join()p2.join()p3.join()print("END!!!!!!!!!!!!!!!!!")
实例3:指定进程为一个类,继承multiprocessing.Process
#-*-coding:utf-8
import multiprocessing
import time#将进程定义为类
#定义一个类,一定要继承multiprocessing.Process
class ClockProcess(multiprocessing.Process):#初始化方法def __init__(self, interval):multiprocessing.Process.__init__(self)self.interval = interval#进程p调用start()时,自动调用run()def run(self):print("----子进程开始")n = 5while n > 0:print("the time is {0}".format(time.ctime()))time.sleep(self.interval)n -= 1if __name__ == '__main__':print("===主进程开始")#实例化一个类,这个类继承于multiprocessing.Processp = ClockProcess(3)#调用start方法后,就是在子进程中执行了run方法p.start()p.join()print("====主进程结束")
(2) Queue
Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递。
# -*-coding:utf-8
import multiprocessing# Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递def writer_proc(q):try:# put方法用以插入数据到队列中q.put(1, block=False)except:passdef reader_proc(q):try:# get方法可以从队列读取并且删除一个元素print(q.get(block=False))except:passif __name__ == "__main__":# 定义一个队列,用于进程间的数据传递q = multiprocessing.Queue()# 新建一个进程,运行writer_proc方法,将对列传给进程writer = multiprocessing.Process(target=writer_proc, args=(q,))writer.start()# 新建一个进程,运行reader_proc方法,将对列传给进程reader = multiprocessing.Process(target=reader_proc, args=(q,))reader.start()reader.join()writer.join()
2、 多线程
Python中的多线程其实并不是真正的多线程,是单线程利用GIL锁(global interpreter lock 全局解释器锁)模拟实现了的多线程。
Python中多线程模块有thread模块和threading模块,推荐使用threading模块,因为threading模块已经封装了现车的同步问题,使用起来更加方便。
(1) 多线程实例
# -*-coding:utf-8
import time
from threading import Thread# 多线程实现def loop(name, seconds):print('子线程开始:', name, ' at:', time.ctime())time.sleep(seconds)print('子线程结束:', name, ' at:', time.ctime())if __name__ == '__main__':loops = [2, 4]nloops = range(len(loops))threads = []print('主进程开始 :', time.ctime())for i in nloops:t = Thread(target=loop, args=(i, loops[i],))threads.append(t)for i in nloops:threads[i].start()for i in nloops:threads[i].join()print('主进程结束 :', time.ctime())输出:
主进程开始 : Tue Oct 31 07:48:05 2017
子线程开始: 0 at: Tue Oct 31 07:48:05 2017
子线程开始: 1 at: Tue Oct 31 07:48:05 2017
子线程结束: 0 at: Tue Oct 31 07:48:07 2017
子线程结束: 1 at: Tue Oct 31 07:48:09 2017
主进程结束 : Tue Oct 31 07:48:09 2017
(2) 队列
#-*-coding:utf-8
import queue#队列# 定义一个队里,默认是先入先出
q = queue.Queue()
# 判断是否为空,空返回True
print(q.empty())
q.put("d1")
q.put("d2")
q.put("d3")# 判断是否满,满返回True
print(q.full())
print(q.get()) # d1
print(q.get()) # d2
print(q.get()) # d3# 阻塞 可以使用q.get(timeout = 1)设置超时来解决阻塞问题,抛出queue.Empty异常
print(q.get(timeout=1))
# 接上一行的例子,还可以设置不要等待,没有数据即刻抛出异常
print(q.get_nowait())
# 或者使用if判断qsize是否等于0
print(q.qsize())
# block参数False也可以解决程序阻塞问题
print(q.get(block=False))# 设置具有长度限制的队列
q = queue.Queue(maxsize=3) # 长度为3
q.put(1)
q.put(2)
q.put(3)
# 这里程序又阻塞了,所以可以使用block,timeout参数解决阻塞问题,异常queue.Full
q.put(4, block=False)# 设置优先级队列,数字小的优先级高
q = queue.PriorityQueue()
q.put((1, "King"))
q.put((-1, "Jeson"))
q.put((10, "Tim"))
q.put((5, "Mike"))print("后入先出-------")
q = queue.LifoQueue() #设置后入先出队列
q.put(1)
q.put(2)
q.put(3)
print(q.get())
print(q.get())
print(q.get())
(3) 实现的生产者消费者实例
# -*-coding:utf-8
import queue
import threading
import time# 生产者消费者模型q = queue.Queue(maxsize=10)# 生产者,每隔0.5秒就生产一个骨头
def producer(name):count = 1while True:# 生成一个骨头,放入队列q.put("骨头%s" % count)print(name, "生产了骨头", count)count += 1time.sleep(0.5)# 消费者,每隔1秒就从队列里拿出一个骨头
def consumer(name):while True:print("[%s]取到[%s]并且吃了它..." % (name, q.get()))time.sleep(1)# 定义一个生产者线程
p = threading.Thread(target=producer, args=("Tim",))
# 定义两个消费者线程
c1 = threading.Thread(target=consumer, args=("King",))
c2 = threading.Thread(target=consumer, args=("Wang",))p.start()
c1.start()
c2.start()
(4) 实例:
import threading
import timelock = threading.Lock()class MyThread(threading.Thread):def __init__(self, func, args, name=''):threading.Thread.__init__(self)self.name = nameself.func = funcself.args = argsdef run(self):print(self.name, "开始了......")#调用传递进来的方法self.func(self.args)def matter1(music):for i in range(0, len(music)):print("第", str(i + 1), "首歌是:", str(music[i]))time.sleep(2)print("切换到下一首歌...")def matter2(number):lock.acquire()j = 0while j <= number:print("我准备写入第", str(j + 1), "行代码")j = j + 1time.sleep(1)print("写入一行代码")lock.release()def matter3(snacks):lock.acquire()for k in range(0, len(snacks)):print("我正在听这歌吃", str(snacks[k]), "零食")time.sleep(5)print("吃完一个零食")lock.release()if __name__ == '__main__':music = ["music1", "music2", "music3"]number = 2snacks = ["咪咪", "辣条"]start = time.time()thing1 = MyThread(matter1, music, "听歌线程")thing2 = MyThread(matter2, number, "打码线程")thing3 = MyThread(matter3, snacks, "零食线程")thing1.start()thing2.start()thing3.start()thing1.join()thing2.join()thing3.join()end = time.time()print("完成时间", str(end - start))
六、 IO
1、 读取文件
(1) 读取整个文件
def readFile():# with关键字是在文件不再使用后,将文件关闭。# open是打开指定的文件,as 是将open返回的对象存入变量file_object中with open('1.txt') as file_object:contents = file_object.read()print(contents)if __name__ == '__main__':readFile()
(2) 逐行读取
def readFile():# with关键字是在文件不再使用后,将文件关闭。# open是打开指定的文件,as 是将open返回的对象存入变量file_object中with open('1.txt') as file_object:# 逐行读取数据for line in file_object:# rstrip是去除末尾的回车符号print(line.rstrip())if __name__ == '__main__':readFile()
(3) 读取的行放入列表
def readFile():# with关键字是在文件不再使用后,将文件关闭。# open是打开指定的文件,as 是将open返回的对象存入变量file_object中with open('1.txt') as file_object:# 将读取的行放入一个列表中lines = file_object.readlines()print(lines)if __name__ == '__main__':readFile()
2、 写入文件
(1) 写入空文件
def writeFile():# open是打开指定的文件,w是以写入模式打开文件with open('2.txt', 'w') as file_object:for i in range(0, 10):# write不会写入换行符,如果要换行,可以使用\nfile_object.write(str(i) + "\n")if __name__ == '__main__':writeFile()
写入文件也需要先打开文件,第二个参数是指定以什么模式打开文件,w是写入模式,a是追加模式,r是只读模式,r+是可读可写模式。当为w时,如果文件不存在就新建,如果存在就请空文件后写入。
(2) 追加写入文件
def writeFile():# open是打开指定的文件,a是以追加模式打开文件with open('2.txt', 'a') as file_object:for i in range(10, 20):# write不会写入换行符,如果要换行,可以使用\nfile_object.write(str(i) + "\n")if __name__ == '__main__':writeFile()
3、 删除文件
import os
os.remove("2.txt")
4、 目录操作
import os# 创建一个目录
os.mkdir("bf")
# 删除一个目录
os.rmdir("bf")
# 获取当前目录路径
print(os.getcwd())
七、 面向对象
1、 类
(1) 定义一个类
# 定义个名为Dog的类
class Dog():"""小狗类"""#__init__方法是一个初始化方法,是个特殊的函数,当创建类时会自动执行这个初始化函数。#前后的下划线是一种约定的格式,目的是区分普通函数。#self是指当前类的实例。def __init__(self, name, age):"""初始化方法"""self.name = nameself.age = age#定义了函数,参数self是指当前类的实例,在函数中可以使用当前实例。def sit(self):"""小狗蹲下"""print(self.name.title() + "is sitting")def roll_over(self):"""小狗打滚"""print(self.name.title() + "rolled over")
(2) 实例化类
#根据类的初始化函数创建一个类的实例
my_dog = Dog("jock", 3)
#调用类实例的函数
my_dog.sit()
#使用属性
print(my_dog.name)
class Single():c = 1def __setattr__(self, key, value):self.__dict__[key] = valuepassdef __init__(self, x):print(x)def __init__(self):print("1111")def add(self, x, y):print(x + y)def add(self, x, y, z):print(x + y + z)s = Single()
s.add(1, 2)
类都有一个默认的初始化方法init,实例化类时会自动调用这个初始化方法,一个类只能有一个init方法。如果定义了多个,以最后一个为准。
另外Python类里普通的方法也不支持重载,如果有多个相同名称的方法,后面的方法会覆盖前面的方法。
(3) 私有方法
class Person():def eat(self):print("吃饭")# 调用私有方法时,要使用self来调用。self.__sleep()# 方法名称前面添加两个下划线,这个方法是就私有方法# 私有方法不能被类外部调用,只能在本类中调用def __sleep(self):print("睡觉")passzs = Person()
zs.eat()
# #外部是不能调用私有方法的
# sz.__sleep()
(4) 变量
class Person():# 共有变量age = 20# 私有变量名前面要有两个下划线__happy = Truedef eat(self):print("吃饭")# 调用私有方法时,要使用self来调用。self.__sleep()# 方法名称前面添加两个下划线,这个方法是就私有方法# 私有方法不能被类外部调用,只能在本类中调用def __sleep(self):# 调用私有变量,需要加selfif self.__happy:print("不睡觉")else:print("睡觉")passzs = Person()
zs.eat()
# #外部是不能调用私有方法的
# sz.__sleep()
print(zs.age)
print(Person.age)# print(zs.__happy) #外部不能调用私有变量
(5) 特殊类属性
class Person():'''类的描述信息'''# 共有变量age = 20# 私有变量名前面要有两个下划线__happy = Truepasszs = Person()# 当前所在模块名称
print(__name__)
# 类的名称
print(Person.__name__)
# 类描述文档
print(Person.__doc__)
# 类所属模块
print(Person.__module__)
# 类所有的父元素组成的元组
print(Person.__bases__)
# 类属性组成的字典(包括变量和方法)
print(Person.__dict__)
# 类对象的类型
print(Person.__class__)
2、 继承
一个类可以继承另外一个类,这两个类分别被称为子类和父类。
(1) 定义子类
# 定义个名为Dog的类
class Dog():"""小狗类"""#__init__方法是一个初始化方法,是个特殊的函数,当创建类时会自动执行这个初始化函数。#前后的下划线是一种约定的格式,目的是区分普通函数。#self是指当前类的实例。def __init__(self, name, age):"""初始化方法"""self.name = nameself.age = age#定义了函数,参数self是指当前类的实例,在函数中可以使用当前实例。def sit(self):"""小狗蹲下"""print(self.name.title() + "is sitting")def roll_over(self):"""小狗打滚"""print(self.name.title() + "rolled over")#定义一个子类,机器狗,继承Dog类
class MachineDog(Dog):"""机器狗类"""def __init__(self,name,age):#调用父类的初始化方法,完成父类的初始化super().__init__(name,age)#实例化一个子类
m_dog=MachineDog("mdog",1)
#调用子类继承来的方法
m_dog.sit()
这个例子是定义了一个机器狗类,继承Dog类。子类和父类必须要在一个文件中,切父类要在子类前面。
(2) 多继承
子类可以继承于多个父类,这就涉及到如果多个父类中有相同名称的方法时,调用哪个方法,Python遵循从左到右,深度优先的原则。
class AA:def a(self):print("a")class BB:def a(self):print("cc")class CC(AA, BB):passc = CC()
c.a()
输出为:
a
3、 导入类
可以在另外一个py文件中导入类。
from dog import Dog,MachineDogif __name__ == '__main__':#根据类的初始化函数创建一个类的实例my_dog = Dog("jock", 3)#调用类实例的函数my_dog.sit()#使用属性print(my_dog.name)#实例化一个子类m_dog=MachineDog("mdog",1)#调用子类继承来的方法m_dog.sit()
八、 异常处理
1、 try-except代码块
if __name__ == "__main__":try:print(3 / 0)except ZeroDivisionError:print("不能除以0")
if __name__ == "__main__":try:print(3 / 0)except ZeroDivisionError as e:print("不能除以0", e)
2、 else
if __name__ == "__main__":number = int(input("请输入数字:\n"))try:n = 80 / numberexcept ZeroDivisionError:print("不能除以0")else:print("结果为:" + str(n))
3、 自定义异常
#自定义了一个异常类,要继承Exception类
class NotFondNameException(Exception):def __init__(self):print("没有发现名称异常初始化了")passdef test(name):if name == "0":#抛出指定异常raise NotFondNameExceptiontry:test("0")
except NotFondNameException as e:print("截获了异常:")
finally:print("不管是否异常,都会这行这里!")
本文标签: AI
版权声明:本文标题:【AI 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/p/1700273048a374516.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论