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 除以 yb / 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

运算符逻辑表达式描述实例
andx and y布尔”与” - 如果 x 为 False,x and y 返回 False,否则它返回 y 的计算值。(a and b) 返回 20。
orx or y布尔”或” - 如果 x 是 True,它返回 x 的值,否则它返回 y 的计算值。(a or b) 返回 10。
notnot 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) 身份运算符

运算符描述实例
isis 是判断两个标识符是不是引用自一个对象x is y , 类似 id(x) == id(y) , 如果引用的是同一个对象则返回 True,否则返回 False
is notis 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