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()方法去创建具体的类对象

优点:

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

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

相关推荐
听风吟丶8 分钟前
Java 函数式编程深度实战:从 Lambda 到 Stream API 的工程化落地
开发语言·python
饮长安千年月1 小时前
玄机-第八章 内存马分析-java03-fastjson
开发语言·python·安全·web安全·网络安全·应急响应
天天爱吃肉82181 小时前
新能源汽车动力系统在环(HIL)半实物仿真测试台架深度解析
人工智能·python·嵌入式硬件·汽车
卡次卡次11 小时前
注意点:挂载与插硬盘,容器挂载实现持久化存储
python
2401_841495642 小时前
【LeetCode刷题】找到字符串中所有字母异位词
数据结构·python·算法·leetcode·数组·滑动窗口·找到字符串中所有字母异位词
MediaTea2 小时前
Python 第三方库:OpenPyXL(Excel 文件读写与操作)
开发语言·python·excel
自学互联网2 小时前
python爬虫入门案例day05:Pexels
开发语言·爬虫·python
再__努力1点3 小时前
【11】特征检测与匹配:AKAZE特征算法详解与实现
人工智能·python·opencv·算法·计算机视觉·特征提取
麦麦大数据3 小时前
F046 新闻推荐可视化大数据系统vue3+flask+neo4j
python·flask·vue3·知识图谱·neo4j·推荐算法
MediaTea3 小时前
Python 第三方库:Markdown(将文本渲染为 HTML)
开发语言·前端·python·html