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

优点:

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

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

相关推荐
四口鲸鱼爱吃盐7 分钟前
Pytorch | 利用PI-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击
人工智能·pytorch·python
小陈phd25 分钟前
深度学习之超分辨率算法——SRCNN
python·深度学习·tensorflow·卷积
CodeClimb26 分钟前
【华为OD-E卷-简单的自动曝光 100分(python、java、c++、js、c)】
java·python·华为od
liyinuo201733 分钟前
嵌入式(单片机方向)面试题总结
嵌入式硬件·设计模式·面试·设计规范
数据小小爬虫37 分钟前
如何利用Python爬虫获取商品历史价格信息
开发语言·爬虫·python
NiNg_1_23444 分钟前
Python的sklearn中的RandomForestRegressor使用详解
开发语言·python·sklearn
黑色叉腰丶大魔王1 小时前
《基于 Python 的网页爬虫详细教程》
开发语言·爬虫·python
laity171 小时前
爬取小说案例-BeautifulSoup教学篇
爬虫·python
WANGWUSAN661 小时前
Python高频写法总结!
java·linux·开发语言·数据库·经验分享·python·编程
40岁的系统架构师1 小时前
1 JVM JDK JRE之间的区别以及使用字节码的好处
java·jvm·python