Python基础(十)——闭包、装饰器、设计模式与多线程编程

news/2024/9/19 11:12:06 标签: python, 设计模式, 开发语言

十一.高级用法

1.闭包

函数嵌套的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,把这个使用外部函数变量的内部函数称为闭包

解释:

外部函数的参数因为作用域的原因,只是一个临时变量,调用完函数对于外部而言变量就消失了,而内部函数的作用域则为外部函数定义的区域。因此,把原本的全局变量作为参数放入外部函数中,成为局部变量,而该局部变量只能被内部函数访问,从而实现变量的安全化。

适用于:依赖外部全局变量,但是不希望全局变量被访问而修改的情况。

缺点:

由于内部函数持续引用外部函数的值,导致这部分内存空间不被释放,一直占用内存。

python"># 简单的闭包
def outer(num1):
    def inner(num2):
        print(num1+num2)

    return inner # 返回值为内部函数

f1 = outer(50) # f1接收的为一个函数
f1(20)
"""
返回值:
70
"""

# 使用nonlocal关键字修饰外部函数
def outer(num1):
    def inner(num2):
        nonlocal num1
        # 使用nonlocal关键字修饰外部函数的变量,才可以在内部函数中修改它
        num1 = 200
        print(num1+num2)

    return inner # 返回值为内部函数

f1 = outer(50) # f1接收的为一个函数
f1(20)
"""
返回值:
220
"""

# 闭包实现ATM机
def outer(all_money = 0):
    def inner(money, flag=True):
        nonlocal all_money
        if flag:
            all_money += money
            print(f"成功存款{money}元,账户余额为{all_money}元")

        else:
            all_money -= money
            print(f"成功取款{money}元,账户余额为{all_money}元")

    return inner

account = outer()
account(2000, True)
account(500, False)

"""
返回值:
成功存款2000元,账户余额为2000元
成功取款500元,账户余额为1500元
"""
2.装饰器

装饰器也是一种闭包,其功能是在不破坏目标函数原有代码和功能的前提下,为目标函数增加新功能。

  • 一般写法:(闭包写法)执行逻辑

定义闭包函数,函数内部包括:执行目标函数、添加新的功能

python">import random
import time
def outer(func):
    def inner():
        print("我困死要睡觉了")  # 新的功能
        func()    # 执行目标函数
        print("我不得不起床了")  # 新的功能

    return inner

def sleep():  # 目标函数
    print("睡觉中……勿扰……")
    time.sleep(random.randint(1, 10))

fun = outer(sleep)
fun()
"""
返回:
我困死要睡觉了
睡觉中……勿扰……
我不得不起床了
"""
  • 语法糖写法

使用@外部函数,定义在目标函数之上。把sleep函数作为参数传入outer函数,返回inner函数执行了操作逻辑。

python">import random
import time
def outer(func):
    def inner():
        print("我困死要睡觉了")
        func()
        print("我不得不起床了")

    return inner

# @外部函数,定义在目标函数之上
@outer
def sleep():
    print("睡觉中……勿扰……")
    time.sleep(random.randint(1, 10))

sleep()

"""
返回值:
我困死要睡觉了
睡觉中……勿扰……
我不得不起床了
"""
3.设计模式

是一种编程套路思想,面向对象也属于设计模式的一种。

设计模式有多种,可以深入学习。此处仅介绍基础常用的单例模式和工厂模式。

  • 单例模式

某些场景下,需要一个类无论获取多少次类对象,都仅仅提供一个具体的实例,用以节省类对象的开销和内存开销,比如某些工具类,仅需要一个实例,即可在各处使用。

【保证一个类只有一个实例,并提供一个访问它的全局访问点】

使用方式:

在一个文件中定义该类并获得类对象,在另一个文件中通过import导入类对象。

python"># test.py

class tools:
	pass
	
my_tool = tools()

# main.py
from test import my_tool

t1 = my_tool
t2 = my_tool
t3 = my_tool

print(id(t1))
print(id(t2))
print(id(t3))
# t1、t2、t3是同一个对象,地址相同
"""
返回值:
2146066533584
2146066533584
2146066533584
"""
  • 工厂模式

当需要大量创建一个类的实例时,从原生的使用类的构造去创建对象的形式。

优点:

大批量创建对象时有统一的入口,易于维护;

当发生修改时,仅修改工厂类的创建方法即可;

python">class Phone:
    pass

class HuaWei(Phone):
    pass

class XiaoMi(Phone):
    pass

class Honour(Phone):
    pass

class PhoneFactory:
    def get_phone(self, phone_type):
        if phone_type == '1':
            return HuaWei()
        elif phone_type == '2':
            return XiaoMi()
        else:
            return Honour()

pf = PhoneFactory()
phone1 = pf.get_phone('1')
phone2 = pf.get_phone('2')
phone = pf.get_phone('3')
4.进程与线程

**进程:**一个程序运行在系统上则称该程序为一个进程,分配ID方便系统管理。操作系统中可以运行多个进程,即多任务运行。

**线程:**归属于进程,是进程实际工作的最小单位,执行不同的工作。一个进程可以开启多个线程,即多线程运行。

**注意:**进程之间是内存隔离的,不同的进程拥有各自的内存空间。

线程之间是内存共享的,线程是属于进程的,一个进程内的多个线程之间共享进程拥有的内存。

**并行执行:**同时执行不同的工作,进程之间是并行执行的,线程之间也是。

5.多线程

使用threading模块实现。

  • 单线程
python">import time

def sing():
    while True:
        print("唱歌")
        time.sleep(1)

def dance():
    while True:
        print("跳舞")
        time.sleep(1)

if __name__ == '__main__':
    sing()
    dance()

"""
输出:
唱歌
唱歌
唱歌
唱歌
唱歌
唱歌
唱歌
……
"""
  • 多线程
python">import threading
import time

def sing():
    while True:
        print("唱歌")
        time.sleep(1)

def dance():
    while True:
        print("跳舞")
        time.sleep(1)
"""
thread = threading.Thread(group= , target= , name=, args= , kwargs=)
-group: 未来功能的预留参数
-target: 执行的目标任务名
-name: 线程名,一般不用设置
-args: 以元组形式给执行任务传参
-kwargs: 以字典形式给执行任务传参
"""
        
if __name__ == '__main__':
    # 创建唱歌跳舞的线程
    sing_thread = threading.Thread(target=sing)
    dance_thread = threading.Thread(target=dance)
    # 线程工作
    sing_thread.start()
    dance_thread.start()
"""
输出:
唱歌
跳舞
跳舞唱歌
唱歌跳舞
唱歌跳舞
唱歌跳舞
唱歌
跳舞
唱歌跳舞
唱歌跳舞
唱歌跳舞
…………
"""   

import threading
import time

def sing(msg):
    while True:
        print(msg)
        time.sleep(1)

def dance(msg):
    while True:
        print(msg)
        time.sleep(1)

if __name__ == '__main__':
    # 创建唱歌跳舞的线程
    sing_thread = threading.Thread(target=sing, args=("唱歌啦……",))
    dance_thread = threading.Thread(target=dance, kwargs={"msg": "跳舞啦……"})
    # 线程工作
    sing_thread.start()
    dance_thread.start()
    
"""
输出:
唱歌啦……跳舞啦……
跳舞啦……唱歌啦……
唱歌啦……跳舞啦……
唱歌啦……跳舞啦……
跳舞啦……
唱歌啦……
唱歌啦……跳舞啦……
…………
"""

记录学习过程的笔记,欢迎大家一起讨论,会持续更新


http://www.niftyadmin.cn/n/5665413.html

相关文章

HTTPS:构建安全通信的基石

HTTPS(Hypertext Transfer Protocol Secure),作为互联网上安全通信的基石,通过在HTTP基础上引入SSL/TLS协议层,实现了数据传输的加密,确保了信息的机密性、完整性和真实性。这一过程涉及多个精细设计的步骤…

硬件(驱动开发概念)

驱动程序开发 裸机驱动(无操作系统) Linux驱动 以计算机技术为基础,在软件和硬件层间可以被剪裁的专业硬件计算机系统 SOC:片上系统 Kernel:内核 x86 (CISC:complex instruction set computer 复杂指令…

PM2.5粉尘传感器详解(STM32)

目录 一、介绍 二、传感器原理 1.原理图 2.引脚描述 3.工作原理介绍 4.粉尘浓度转化关系 5.空气污染指数 三、程序设计 main.c文件 PM25.h文件 PM25.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 GP2Y1014AU是日本夏普公司开发的一款光学灰尘浓度检测传…

Java 发布jar包到maven中央仓库(2024年9月保姆级教程)

文章目录 前言一、账号准备1. 注册登录账号2. 新建命名空间3. 验证命名空间4. 生成令牌5. 为 maven 设置令牌二、GPG准备1. 下载GPG2. 发布证书2.1 新建证书2.2 发布证书到服务器2.3 验证发布三、发布jar包到中央仓库1. 编辑项目pom文件2. 打包上传3. 发布jar包4. 搜索我们的ja…

CTF 技能树 LOG -GIT泄露 笔记

log 使用虚拟机kali操作 python2 安装 apt-get install python2 进入root用户,下载克隆git hack库 git clone https://github.com/BugScanTeam/GitHack sudo passwd root 修改root 命名密码为root 切换登录 su root 终端进入home/kali/GitHack/ python GitH…

git分支合并时忽略指定文件

分支合并忽略特定文件步骤 1.在项目根目录下cmd窗口运行以下命令 git config merge.ours.driver true2.在项目根目录下新建文件.gitattributes然后文件中写入需要忽略的文件名 mergeours, 一个文件占一行 Dockerfile mergeours /nginx/default.conf mergeours

南大通用数仓-GCDW-学习-02-计算资源管理(物理机版本)

目录 一、环境信息 二、介绍 三、属性 四、gcadmin语法 五、操作 1、创建Warehouse模板 2、配置Warehouse文件 3、创建Warehouse 4、查看Warehouse 5、重命名Warehouse 6、挂起Warehouse (1)语法介绍 (2)示例 &#…

[数据集][目标检测]智慧养殖场肉鸡目标检测数据集VOC+YOLO格式3548张1类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):3548 标注数量(xml文件个数):3548 标注数量(txt文件个数):3548 标注…