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

优点:

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

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

相关推荐
U盘失踪了2 小时前
python JSONPath 表达式生成器
linux·windows·python
山烛4 小时前
决策树学习全解析:从理论到实战
人工智能·python·学习·算法·决策树·机器学习
#六脉神剑5 小时前
接口请求的后台发起确认
低代码·设计模式·产品运营·mybuilder
没有梦想的咸鱼185-1037-16636 小时前
Python科研数据可视化技术
python·机器学习·信息可视化·数据分析
奔波霸的伶俐虫8 小时前
jeecg框架@Dict不生效问题
开发语言·python
徐赛俊8 小时前
# 自动定时运行Python爬虫脚本教程(Windows任务计划程序)
windows·爬虫·python
程序员秘密基地9 小时前
基于html,css,jquery,django,lstm,cnn,tensorflow,bert,推荐算法,mysql数据库
python·cnn·tensorflow·lstm·推荐算法
技术炼丹人9 小时前
从RNN为什么长依赖遗忘到注意力机制的解决方案以及并行
人工智能·python·算法
hqxstudying10 小时前
Java开发时出现的问题---语言特性与基础机制陷阱
java·jvm·python
仪器科学与传感技术博士10 小时前
python:机器学习中的分类与回归怎么理解
python·机器学习·分类