【AI_Python】Python基础

这一篇博文是【 AI学习路线图】系列文章的其中一篇,点击查看目录:AI学习完整路线图

人生苦短,我用Python

一、 概述

这个博文的内容都是基于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 = 1
    print(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")
ifelse:
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+n
    n=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):
        break
    else:
        print(item)
print("=======================")

(4) continue

# 如果是偶数就进入下一个循环
for item in range(1, 10):
    if (item ** 2 % 2 == 0):
        continue
    else:
        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 r

if __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'] = name
    info['age'] = age
    for key, val in otherInfo.items():
        info[key] = val
    print(info)


if __name__ == '__main__':
    userinfo('jock', 20, province='河北', city='廊坊')

(7) 函数嵌套

# 函数嵌套
def fun1():
    def fun2():
        print("function2")

    print("fun1")
    return fun2


if __name__ == '__main__':
    obj = fun1()
    print('-------')
    obj()

函数中可以再定义函数,外层函数可以将内层函数做为一个返回值返回,调用方可以对返回的函数进行执行操作。

(8) 函数闭包

# 函数闭包
def f0(x):
    def f1(y):
        print(x + y)

    return f1


if __name__ == '__main__':
    obj = f0(10)
    obj(20)

(9) 装饰器

# 定义一个装饰器方法,log可以装饰其他方法
def log(func):
    # 定义一个内部方法,将这个方法做为装饰器的返回值,装饰后会执行它
    def wrap(*args, **kwargs):
        # 装饰器内做的工作
        print("添加日志开始")
        # 其中一项工作是执行被装饰的方法
        r = func(*args, **kwargs)
        print("添加日志结束")
        # 将被装饰的方法返回值返回装饰器
        return r

    return 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 r

        return wrap

    return wrap1


# 用@来表示装饰器,加载被装饰方法的头上
@log2(10)
def delete(name):
    print("删除" + name + "操作")
    return "ok"


if __name__ == '__main__':
    # 执行被装饰的方法时,会先执行装饰器,由装饰器来执行delete方法。
    r = delete("jock")
    print(r)

(10) 迭代器

import itertools

a = [1, 2, 3]
b = ['a', 'b', 'c']
x = range(1, 5)
com1 = itertools.combinations(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 = itertools.combinations(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 = 1
    while i <= 9:
        j = 1
        while j <= i:
            print(str(j) + "*" + str(i) + "=" + str(i * j) + "  ", end="")
            j = j + 1
        print("\r")
        i = i + 1

2、 导入整个模块

在另外一个py文件中,导入myprint整个模块

import myprint

if __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 jiujiu

if __name__ == '__main__':
    jiujiu()

这个例子只是导入模块中的一个函数,调用时不用指定模块名,直接使用函数名。

4、 导入所有的函数

from myprint import *

if __name__ == '__main__':
    jiujiu()

这个是将所有的函数都导入到当前模块中,对于其他人的大型模块一定要慎用,因为可能会造成名字冲突。

5、 as指定模块别名

import myprint as mp

if __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 = 5
        while n > 0:
            print("the time is {0}".format(time.ctime()))
            time.sleep(self.interval)
            n -= 1


if __name__ == '__main__':
    print("===主进程开始")
    #实例化一个类,这个类继承于multiprocessing.Process
    p = 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:
        pass


def reader_proc(q):
    try:
        # get方法可以从队列读取并且删除一个元素
        print(q.get(block=False))
    except:
        pass


if __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 = 1
    while True:
        # 生成一个骨头,放入队列
        q.put("骨头%s" % count)
        print(name, "生产了骨头", count)
        count += 1
        time.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 time

lock = threading.Lock()

class MyThread(threading.Thread):
    def __init__(self, func, args, name=''):
        threading.Thread.__init__(self)
        self.name = name
        self.func = func
        self.args = args

    def 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 = 0
    while j <= number:
        print("我准备写入第", str(j + 1), "行代码")
        j = j + 1

        time.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 = 2
    snacks = ["咪咪", "辣条"]

    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不会写入换行符,如果要换行,可以使用\n
            file_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不会写入换行符,如果要换行,可以使用\n
            file_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 = name
        self.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 = 1

    def __setattr__(self, key, value):
        self.__dict__[key] = value
        pass

    def __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("睡觉")

pass

zs = Person()
zs.eat()
# #外部是不能调用私有方法的
# sz.__sleep()
(4) 变量
class Person():
    # 共有变量
    age = 20
    # 私有变量名前面要有两个下划线
    __happy = True

    def eat(self):
        print("吃饭")
        # 调用私有方法时,要使用self来调用。
        self.__sleep()

    # 方法名称前面添加两个下划线,这个方法是就私有方法
    # 私有方法不能被类外部调用,只能在本类中调用
    def __sleep(self):
        # 调用私有变量,需要加self
        if self.__happy:
            print("不睡觉")
        else:
            print("睡觉")


pass

zs = Person()
zs.eat()
# #外部是不能调用私有方法的
# sz.__sleep()
print(zs.age)
print(Person.age)

# print(zs.__happy) #外部不能调用私有变量
(5) 特殊类属性
class Person():
    '''类的描述信息'''
    # 共有变量
    age = 20
    # 私有变量名前面要有两个下划线
    __happy = True

pass

zs = 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 = name
        self.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):
    pass


c = CC()
c.a()
输出为:
a

3、 导入类

可以在另外一个py文件中导入类。

from dog import Dog,MachineDog

if __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 / number
    except ZeroDivisionError:
        print("不能除以0")
    else:
        print("结果为:" + str(n))

3、 自定义异常

#自定义了一个异常类,要继承Exception类
class NotFondNameException(Exception):
    def __init__(self):
        print("没有发现名称异常初始化了")

pass


def test(name):
    if name == "0":
        #抛出指定异常
        raise NotFondNameException


try:
    test("0")
except NotFondNameException as e:
    print("截获了异常:")
finally:
    print("不管是否异常,都会这行这里!")
  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值