1.闭包案例
在函数嵌套的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,我们把这个使用外部函数变量的内部函数称为闭包. 外层函数: config_name(),外层函数中的变量是 name 内层函数: inner(),inner()使用了外层函数的变量name. 内层函数闭包了name变量.延长了name的声明周期. 调用外层函数,返回了内层函数.此时.内层函数中有name变量.def config_name(name): age = 19 def inner(info): print(f"{name}:{info}") return inner if __name__ == '__main__': # 调用外层函数,返回了内层函数,此时fun1 就是 内层函数inner() fun1 = config_name("小明") fun1('你好') fun1('交个朋友吧') fun2 = config_name('小红') fun2('不想和你玩') # 闭包可以让变量更安全 # g_name = '小明' # 此时其它模块也可以访问和修改. def outer(): g_name = '小明' #被闭包的g_name 其它模块无法直接访问. def say_info(info): print(f"{g_name}:{info}") return say_info if __name__ == '__main__': aaa = outer() aaa('你好')
2.装饰器案例
@classmethod 装饰类方法.
@staticmethod 装饰静态方法.
""" 需求: 有一个函数 sleep(),在函数执行前打印 '准备睡觉.',在函数执行后打印'休息完毕-元气满满' """#装饰器实际就是闭包 def outer(fun): def inner(): print('准备睡觉') fun() print('休息完毕-元气满满') return inner #1.被装饰的函数会当做参数传递给装饰器. outer(sleep) #2.被装饰的函数最终会被装饰器的返回值替换.sleep() = inner() #3.以后调用sleep函数 其实执行的是inner()函数. @outer def sleep(): print("休息6小时就够了") if __name__ == '__main__': #方案1 --不够优雅 # print('准备睡觉') # sleep() # print('休息完毕-元气满满') #方案2: 使用闭包来完成 # inner = outer(sleep) # inner() # 方案3: 使用装饰器来完成 sleep()
3.通用装饰器[了解]
#需求: 在计算求和函数之前输出一句话.'正在努力计算中....'# 装饰器名称简明之意: logging -- 打印日志的意思 def logging(func): #内层函数即使用来替换被装饰的函数用的. def inner(*args): print('正在努力计算中....') result = func(*args) return result return inner #定义一个求和的函数 @logging def sum_num(a,b): c = a+b return c @logging def bbb(a,b): return a*b @logging def sum_num_plus(*args): my_sum = 0 #遍历容器,容器中的值会不断的赋值给 i 变量 for i in args: my_sum += i return my_sum if __name__ == '__main__': res = sum_num(10,20) print(res) print(bbb(10, 5)) print(sum_num_plus(1,2,3,4))
4.了解多任务
任务是指在同一时间内执行多个任务
最大好处是充分利用CPU资源,提高程序的执行效率
并发:交替执行
并行: 同时执行
5.了解进程
一个正在运行的程序或者软件就是一个进程,它是操作系统进行资源分配的基本单位,
也就是说每启动一个进程,操作系统都会给其分配一定的运行资源(内存资源)保证进程的运行。
6.多进程编程
import multiprocessing import time def sing(): for i in range(3): print('唱歌') time.sleep(1) def dance(): for i in range(3): print('跳舞') time.sleep(1) if __name__ == '__main__': #让唱歌和跳舞同时执行--交替执行 #开启新的进程去执行任务.创建进程对象 p1 = multiprocessing.Process(target=sing) # 使用进程对象去开启任务. p1.start() # 创建进程对象 p2 = multiprocessing.Process(target=dance) # 使用进程对象去开启任务. p2.start()
7.获取进程的编号
获取当前进程编号
os.getpid()
获取当前父进程编号
os.getppid()
获取当前进程对象
multiprocessing.current_process()
获取当前进程编号 os.getpid() 获取当前父进程编号 os.getppid() 获取当前进程对象 multiprocessing.current_process() import multiprocessing import os import time def sing(): for i in range(3): #查看进程编号 print(os.getpid()) #获取到进当前程对象 print(multiprocessing.current_process()) #获取当前进程的父进程 print(os.getppid()) print('唱歌') time.sleep(1) def dance(): for i in range(3): # 查看进程编号 print(os.getpid()) # 获取到进当前程对象 print(multiprocessing.current_process()) # 获取当前进程的父进程 print(os.getppid()) print('跳舞') time.sleep(1) if __name__ == '__main__': #让唱歌和跳舞同时执行--交替执行 #开启新的进程去执行任务.创建进程对象 p1 = multiprocessing.Process(target=sing,name='皇家1号进程') # 使用进程对象去开启任务. p1.start() # 创建进程对象 p2 = multiprocessing.Process(target=dance,name='皇家2号进程') # 使用进程对象去开启任务. p2.start()
8.执行带有参数的任务
import multiprocessing import time #task 任务 def task(count,a,b): # 任务有多个参数.字典必须满足多个值. for i in range(count): time.sleep(1) print(f'任务执行中...{i}') if __name__ == '__main__': #创建进程-- 通过args给任务传递参数--传递的是元组 p1 = multiprocessing.Process(target=task,args=(5,6,7)) p1.start() # 创建进程-- 通过kwargs给任务传递参数 --传递的字典-键必须和任务参数的名称一致. p2 = multiprocessing.Process(target=task,kwargs={"count":3,"a":100,"b":200}) p2.start()
9.多进程共享变量问题
1.进程之间不共享全局变量
2.主进程会等待所有的子进程执行结束再结束
#定义全局列表 import multiprocessing g_list = [] def add_data(): for i in range(1,5): g_list.append(i) print(f'添加数据{i}') print(f'添加完毕--{g_list}') def read_data(): print(f'查看列表:{g_list}') if __name__ == '__main__': p1 = multiprocessing.Process(target=add_data) p1.start() p1.join() p2 = multiprocessing.Process(target=read_data) p2.start() print(f'主进程查看{g_list}') #task 任务 import multiprocessing import time def task(): for i in range(10): time.sleep(0.5) print(f'任务执行中...{i}') if __name__ == '__main__': # daemon = True 设置守护进程-主进程挂了.守护也就挂了. #p1 = multiprocessing.Process(target=task,daemon=True) p1 = multiprocessing.Process(target=task) #p1.daemon = True # daemon = True 设置守护进程-主进程挂了.守护也就挂了. p1.start() time.sleep(3) print('over') p1.terminate()#让子进程终止 # 退出程序 exit()
10.了解线程[概念]:
是进程中执行代码的一个分支,每个执行分支(线程)要想工作执行代码需要cpu进行调度 ,也就是说线程是cpu调度的基本单位,每个进程至少都有一个线程,而这个线程就是我们通常说的主线程。
11.多线程编程
import threading import time def sing(): for i in range(3): print('唱歌') time.sleep(1) def dance(): for i in range(3): print('跳舞') time.sleep(1) if __name__ == '__main__': # Thread([group[, target[, name[, args[, kwargs]]]]]) # group: 线程组,目前只能使用None # target: 执行的目标任务名 # args: 以元组的方式给执行任务传参 # kwargs: 以字典方式给执行任务传参 # name: 线程名,一般不用设置 t1 = threading.Thread(target=sing) t1.start() t2 = threading.Thread(target=dance) t2.start()
12.线程执行带有参数的任务
def task(count): for i in range(count): print(f"任务执行中..{i}") time.sleep(0.2) else: print("任务执行完成") if __name__ == '__main__': #开启线程 --通过args传参 # t1 = threading.Thread(target=task,args=(3,)) # t1.start() # 开启线程 --通过kwargs传参 t2 = threading.Thread(target=task, kwargs={"count":3}) t2.start()
13.线程的注意事项
1.多个线程的执行是无序的
import threading import time def task(): time.sleep(1) #获取当前线程对象.以及名字 print("当前线程:", threading.current_thread().name) if __name__ == '__main__': for i in range(1,6): #链式编程 threading.Thread(target=task,name=f'线程:{i}').start()
2.主线程等待
import threading
import time
def show_info():
print(threading.current_thread())#当前的线程
for i in range(5):
print("test:", i)
time.sleep(0.5)
if __name__ == '__main__':
t1 = threading.Thread(target=show_info,name='小强')
t1.setDaemon(True)# 设置守护线程
t1.start()
time.sleep(2)
print(threading.current_thread())#当前的线程
print('over')
3.线程之间共享全局变量
#定义全局列表 import multiprocessing import threading g_list = [] def add_data(): for i in range(1,5): g_list.append(i) print(f'添加数据{i}') print(f'添加完毕--{g_list}') def read_data(): print(f'查看列表:{g_list}') if __name__ == '__main__': t1 = threading.Thread(target=add_data) t2 = threading.Thread(target=read_data) t1.start() t1.join()#线程加入--优先级提高 t2.start()
4.线程之间共享全局变量数据出现错误问题
import threading g_num = 0 def sum_num1(): for i in range(1000000): global g_num g_num += 1 print("sum1:", g_num) def sum_num2(): for i in range(1000000): global g_num g_num += 1 print("sum2:", g_num) if __name__ == '__main__': #创建两个线程 t1 = threading.Thread(target=sum_num1) t2 = threading.Thread(target=sum_num2) #开启线程 t1.start() t1.join() t2.start()
14.进程和线程的对比