Python笔记11-闭包、装饰器和设计模式

文章目录

闭包

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

示例

css 复制代码
def outer(logo):
    def inner(msg):
        #logo="<"+logo+">"  会报错 表示不认识 logo
        nonlocal logo  #如果要修改 外部函数的值必须使用nonlocal修饰
        logo="<"+logo+">"
        #print(f"<{logo}>{msg}<{logo}>")
        print(f"{logo}{msg}{logo}")
    return inner

fn=outer("mytest")
fn("你好")  #<mytest>你好<mytest>

需要使用nonlocal关键字修饰外部函数的变量才可在内部函数中修改它

优点,使用闭包可以让我们得到:

无需定义全局变量即可实现通过函数,持续的访问、修改某个值

闭包使用的变量的所用于在函数内,难以被错误的调用修改

缺点:

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

装饰器

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

如我们希望给sleep函数,增加一个功能:

在调用sleep前输出:我要睡觉了

在调用sleep后输出:我起床了

css 复制代码
def sleep():
    import random
    import time
    print("睡眠中.....")
    time.sleep(random.randint(1,3))
sleep()

可以借助闭包的功能

定义一个闭包函数, 在闭包函数内部:

执行目标函数

同时添加想要的功能

css 复制代码
def sleep():
    import random
    import time
    print("睡眠中.....")
    time.sleep(random.randint(1,3))

def outer(func):
    def inner():
        #print(f"<{logo}>{msg}<{logo}>")
        print(f"我要睡觉了...")
        func()
        print(f"我要起床了...")
    return inner

fn = outer(sleep)
fn()

装饰器的语法糖:可以使用注解的方式来使用闭包

css 复制代码
def outer2(func):
    def inner2():
        #print(f"<{logo}>{msg}<{logo}>")
        print(f"我要睡觉了...")
        func()
        print(f"我要起床了...")
    return inner2
@outer2   # 增加注解
def sleep():
    import random
    import time
    print("睡眠中.....")
    time.sleep(random.randint(1,3))
sleep()

设计模式

设计模式是一种编程套路,可以极大的方便程序的开发。

最常见、最经典的设计模式,就是我们所学习的面向对象了。

除了面向对象外,在编程中也有很多既定的套路可以方便开发,我们称之为设计模式:

单例、工厂模式、 建造者、责任链、状态、备忘录、解释器、访问者、观察者、中介、模板、代理模式等等模式

这里我挑选了2个经常用到的单例、工厂模式进行了解。

单例模式

某些场景下, 我们需要一个类无论获取多少次类对象,都仅仅提供一个具体的实例

用以节省创建类对象的开销和内存开销

比如某些工具类,仅需要1个实例,即可在各处使用,这就是单例模式所要实现的效果

单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。

在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

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

适用场景:当一个类只能有一个实例,而客户可以从一个众所周知的访问点访问它时。

实现方式:

1.在一个文件中定义类并创建对象

css 复制代码
class StrUtil:
    pass

str_util = StrUtil()

2.另一个文件中直接导入对象使用

css 复制代码
from imp_file import str_util
sutil1 = str_util
sutil2 = str_util
print(sutil2)#<imp_file.StrUtil object at 0x000001A13030A050>
print(sutil1)#<imp_file.StrUtil object at 0x000001A13030A050>

工厂模式

当需要大量创建一个类的实例的时候, 可以使用工厂模式。

即,基于工厂提供的方法去创建对象,可以太容易控制对象创建逻辑。

一般情况下创建对象:

css 复制代码
class Person:
    pass
class Worker(Person):
    pass
class Student(Person):
    pass
class Teacher(Person):
    pass
worker = Worker()
stu = Student()
teacher = Teacher()

工厂模式创建对象:

css 复制代码
class Person:
	pass
class Worker(Person):
	pass
class Student(Person):
	pass
class Teacher(Person):
	pass
class Factory:
    def get_person(self,p_type):
        if p_type=='w':
            return Worker()
        if p_type=='s':
            return Student()
        else:
            return Teacher()

factory = Factory()
worker = factory.get_person('w' )
stu = factory.get_person('s')
teacher = factory.get_person('t')

使用工厂类的get_person()方法去创建具体的类对象

优点:

大批量创建对象的时候有统一的入口,易于代码维护,当需要修改创建逻辑时,仅修改工厂类的创建方法即可

符合现实世界的模式,即由工厂来制作产品(对象)

相关推荐
一朵小花几秒前
Python中with的用法
python
m0_7482323924 分钟前
基于OpenCV和Python的人脸识别系统_django
python·opencv·django
dme.1 小时前
Python爬虫selenium验证-中文识别点选+图片验证码案例
爬虫·python
东方-教育技术博主1 小时前
wps中zotero插件消失,解决每次都需要重新开问题
python
FLZJ_KL1 小时前
【设计模式】【创建型模式】单例模式(Singleton)
java·单例模式·设计模式
镰圈量化1 小时前
当电脑上有几个python版本Vscode选择特定版本python
开发语言·vscode·python
宇努力学习2 小时前
如何本地部署seepseek
python·ai·ollama·deepseek
橙狮科技2 小时前
使用 GPTQ 进行 4 位 LLM 量化
人工智能·python·语言模型
开开心心就好2 小时前
娱乐使用,可以生成转账、图片、聊天等对话内容
windows·python·智能手机·软件工程·娱乐·软件需求
愚昧之山绝望之谷开悟之坡2 小时前
ragflow-RAPTOR到底是什么?请通俗的解释!
python