Python 闭包装饰器和多任务--闭包,装饰器,进程,线程

news2025/1/10 17:37:16

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.进程和线程的对比

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/561785.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

34从零开始学Java之构造方法都有哪些特性?

作者:孙玉昌,昵称【一一哥】,另外【壹壹哥】也是我哦 千锋教育高级教研员、CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者 前言 在前面的几篇文章中,壹哥给大家介绍了不少关于方法的内容,这些内容是我们日常…

zabbix监控之javasnmp自定义监控

1、客户端开启 java jmxremote 远程监控功能 上传 tomcat 软件包到 /opt 目录中 cd /opt tar zxvf apache-tomcat-9.0.16.tar.gz mv apache-tomcat-9.0.16 /usr/local/tomcat #配置 java jmxremote 远程监控功能 vim /usr/local/tomcat/bin/catalina.sh ...... #位置在 cygw…

嵌入式音视频开发面试过程遇到的问题!

前言: 今天继续给大家分享音视频面试过程会被常问到的一些问题! 面试的具体题目: 1、说一下播放器的设计过程: 这里的话主要分以下几步完成: 开启一个线程进行解封装操作 , 这包括:读取音频、视频的压缩数据…

chatgpt赋能Python-python_ps图片

Python PS图片的SEO指南 Python在数字图像处理中广泛应用。其中,Photoshop文件(psd)是一种常见的图像文件格式。但是,如何在搜索引擎上优化Python PS图片并提高其排名仍然是一个挑战。 什么是Python PS图片? Python…

数据结构和算法基础学习1

​​​​​​​ 网址第01周b--1.1数据结构研究_哔哩哔哩_bilibili

学C的第十九天【实用调试技巧:1. 调试;2. Windows环境调试介绍;3. 一些调试的实例;4. 一些调试的实例】

相关代码gitee自取:C语言学习日记: 加油努力 (gitee.com) 接上期:学C的第十八天【指针初阶:5. 指针和数组、6. 二级指针、7. 指针数组;初识结构体:1. 结构体的声明、2. 结构体成员的访问、3. 结构体传参&#xff1b…

java中的栈、堆、方法区

栈(stack) Java栈与堆不同每一个线程都有一个stack,栈的区域非常小,大概只有1M左右,但是存储速度非常快,所以我们把快速执行的任务存储在stack。 特点:自动分配,连续空间&#xff0…

如何从文档中提取结构化数据?parsio.io

parsio.io 产品名:Parsio电子邮件解析器 技术:采用人工智能技术的电子邮件解析器。 支持多种格式: 可以解析电子邮件和附件中的数据,包括PDF、HTML、XLSX(Excel)、CSV、DOCX、XML、TXT等格式。 提取模版&am…

FANUC机器人作为EtherCAT通信从站的相关配置方法

FANUC机器人作为EtherCAT通信从站的相关配置方法 基本介绍: 前提条件: 硬件部分: 机器人需要使用EtherCAT从站板卡 A20B-8101-0821。使用带屏蔽层的网线连接板卡和PLC的网口。 本例中使用的网络接口为EC-IN(CD38Y) 软件部分: 机器人需要安装软件:1A05B-2600-J743! Et…

NLog使用

Nlog 日志组件的使用 这个博文关注 .net framework下的NLog日志组件的使用. 在项目中需要将日志写到日志文件中, 另外一些重要信息要显示在界面上. 使用 NLog 可以轻松做到这点.NLog wiki 页面 nuget 安装两个主要组件 NLogNLog.Windows.Forms 使用总结 日志文件 layout 按照 j…

程序员的 Windows 工具箱「GitHub 热点速览」

作者:HelloGitHub-小鱼干 如何精简 Windows 并快速配置开发环境呢?本周特推的 winutil 是一个程序员的 Windows 工具箱,它提供了开发工具的一键安装以及减少系统垃圾的功能,一切为了简洁、高效。同样高效的还有 C 日志库 spdlog&a…

对讲机亚音是什么?有什么作用?

一、对讲机亚音是什么? 对讲机亚音又被称为亚音频。是比音频信号频率更低的一种特殊信号,目的在于检查信号是否合法,是否对信号进行响应。 亚音是一种特殊的振幅信号,人耳无法感觉也无法听闻到这些信号,所以对于无线…

mac mongodb 安装及配置

1.官网下载地址:MongoDB: The Developer Data Platform | MongoDB 2.下载好压缩包,解压后放在想放的地方,例如: /Users/xiaokeai/environment/mongodb-macos-x86_64-5.0.18 3.打开终端后,在家目录中打开.bash_profil…

Linux系统编程学习 NO.4 ——基础指令学习、操作系统时间的概念、文件压缩包的概念

1.时间相关的概念以及指令 1.1.时间相关的指令 1.1.1.date指令 date可以指定时间显示的格式:date 指定格式 选项 %H:小时 %M:分钟 %S:秒数 %Y:年份 %m:月份 %d:日 %F:相当于%Y-%m-%d %X:相当…

java网络编程从0到1快速上手

目录 网络编程概述 网络基础 网络编程的目的 网络通信要素概述 通信要素1:ip地址及端口号 IP 地址:InetAddress 端口号 InetAddress类 通信要素2:网络协议 网络协议概述 TCP/IP协议簇 TCP 和 UDP ​Socket Socket类的常用构造…

都什么年代了你还不学习postgreSQL(入门篇)

postgreSQL学习 一,简介 1.什么是postgresql https://www.postgresql.org/#官网​ PostgreSQL 是一个功能强大的开源对象关系数据库系统,它使用和扩展了 SQL 语言,并结合了许多安全存储和扩展最复杂数据工作负载的功能。PostgreSQL的起源可…

消息队列对比

目录 什么是消息队列 常用的消息队列工具对比 1 、ActiveMQ 2 、RabbitMQ 3、Kafka 4、 RocketMQ 什么是消息队列 消息队列是分布式应用间交换信息的重要组件,消息队列可驻留在内存或磁盘上, 队列可以存储消息直到它们被应用程序读走。通过消息队列&#xff0…

docker 镜像和容器

一、简述 win系统常用Ghost技术来做镜像,把系统和系统上安装的应用程序一起打包做备份,在别的电脑上安装这个GHO镜像则会有和源系统一摸一样的系统和应用。 docker功能类似,而且是分层的,在拉取镜像时候可见。 docker镜像拉取下…

4、js - 闭包

1、闭包的概念 闭包:函数嵌套函数,内层函数访问了外层函数的局部变量。 // 闭包 function func1() {let a 9;let b 8;function func2() {console.log("a", a); // a 9}func2(); } func1(); 分析: 需要访问的变量会被放到闭包…

用YOLOv5和MobileViTs骨干网络革新目标检测:高效准确AI视觉的未来

目录 一、YOLOv51、YOLOv5介绍2、YOLOV5的整体架构图3、MobileViT介绍 二、YOLOv5与MobileViT的结合1、YOLOv5网络结构回顾2、MobileViT网络结构介绍3、YOLOv5替换骨干网络为MobileViT的优势 三、MobileViT的细节与实现1、ViT与MobileNetV3的结合2、MobileViT网络结构细节3、Mo…