IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> python 闭包 装饰器 -> 正文阅读

[Python知识库]python 闭包 装饰器

1 闭包:保小

闭包

函数内的属性,都是有生命周期的,都是在函数执行期间,函数执行完,就会被回收。但可以通过闭包,将函数内的属性给保留下来,除非通过 del 删除掉,否则就是存在的。

内部函数对外部函数作用域(肚子里的东西)里变量的引用

def func():  # 外部函数
    print("this is function")

    def func1():  # 内部函数
        print("this is function1")
func()
#输出
# this is function

若我想用func1,该怎么办呢?将func1()返回就可以用了啊

def func():  # 外部函数
    print("this is function")

    def func1():  # 内部函数
        print("this is function1")
    return func1


var = func()  # 这时候return回来func1
var()   # var == func1,var()==func1()
#输出
#this is function
#this is function1
# 一个真正意义上闭包的例子:函数层面的
# 内部函数对外部函数作用域里 *变量* 的引用(仔细理解)

def func():  # 外部函数
    a = 1  # 外部函数作用域里的变量
    print("this is function")

    def func1(num):  # 内部函数
        print("this is function1")
        print(num + a)   # 将外部a的保下来。通过return func1函数保下来
        # (内部函数对外部函数作用域里 *变量* 的引用)

    return func1  # 返回func1的函数名


var = func()  # 这时候return回来func1
var(3)   # var == func1,var()==func1()
# 输出
# this is function
# this is function1
# 4

但是此时a是在var里面的,若def val,那么此时a才会被真正意义的删除。(看下面的例子),我们会发现obj其实是没有被删除的,obj[0] 仍然在叠加的状态。

mylist = [1, 2, 3, 4]


def func(obj):
    print('func', obj)

    def func1():
        obj[0] += 1
        print("func1", obj)

    return func1


var = func(mylist)
var()
var()
var()

# 输出
#func [1, 2, 3, 4]
#func1 [2, 2, 3, 4]
#func1 [3, 2, 3, 4]
#func1 [4, 2, 3, 4]

闭包的意义:闭包是func(),闭包函数func1()
闭包内的闭包函数func1私有化了变量,完成了数据的封装,类似于面向对象。

2 装饰器(也叫语法糖 @)

装饰器存在的意义:不影响原有函数的功能,而且还可以添加新的功能。
场景:对不可修改的第三方API进行添加新功能。

2.1 装饰器

# 装饰器 基于闭包
def func1(func):  # 闭包函数的参数是外部闭包函数的参数,func是被装饰的函数对象, func是形参函数!
    def func2():
        print("aaaabbbb")
        return func()  # 返回了外部函数接收的参数被装饰函数的调用

    return func2


# return func  返回了函数名
# return func()  返回的是一个函数调用
@func1  # 相当于 myprint = func1(myprint),这就是装饰器的功能
def myprint():
    print("你好,我是print")


myprint()  # 由于被装饰了,所以此处执行的实际为func1(myprint)(),接收被装饰的函数作为参数,而且还要被继续调用一次

# 流程:
# @func1相当于myprint == func1(myprint) 得到func2,即myprint=func2
# 而myprint() = func2(),所以执行func2(), 然后得到print("aaaabbbb"),然后得到func(),
# 而func=myprint,所以func()=myprint(),打印出print("你好,我是print")

# myprint()==func2()+func()
# 而func==myprint,所以
# myprint()==func2()+myprint()

2.2 装饰器函数带参数:多一层包装来接收装饰器的参数

# 要求:
# 调用men()时候,print("好好上班。你不可以生娃")
# 调用women()时候,print("好好上班。你可以生娃")
# def men():
#     print("好好上班。")

# def women():
#     print("好好上班。")


def func1(func,sex):
    def func2():
        if sex == "men":
            print("你不可以生娃")
        if sex == "women":
            print("你可以生娃")
        return func()

    return func2


@func1(sex='men')
def men():
    print("好好上班。")


@func1(sex='women')  # 但是这样会报错,所以其实还需要一个外层函数
def women():
    print("好好上班。")


men()  # func1(men)()

# 报错
@func1(sex='men')
TypeError: func1() missing 1 required positional argument: 'func'

但是这样会报错,所以其实还需要一个外层函数,如下:


def func0(sex):
    def func1(func):
        def func2():
            if sex == "men":
                print("你不可以生娃")
            if sex == "women":
                print("你可以生娃")
            return func()

        return func2
    return func1

# 带参装饰器:func0(sex='men')()()
#1、func0(sex='men')——>func1
#2、func1()——>func2  # 用了第一个()
#3、func2()用第二个()——>func()==men()

@func0(sex='men')
def men():
    print("好好上班。")


@func0(sex='women')  # 但是这样会报错,所以其实还需要一个外层函数
def women():
    print("好好上班。")


men()  # men()相当于func0(sex='men')()()
women()

# 输出
你不可以生娃
好好上班。
你可以生娃
好好上班。

2.3 被装饰的函数带参数:只需要在最内部函数传入

# 求和:接收两个参数。
# 实现被装饰函数,接收两个参数,并return a+b的值,并希望a,b本身都+5,不允许在mysum中实现。

def func1(func):
    def func2(x, y):
        print(x, y)
        x += 5
        y += 5
        # x = 'a'
        # y = 'b'
        # 最后会实现:1+2 = ab
        return func(x, y)

    return func2


@func1
def mysum(a, b):
    print(a + b)


mysum(1, 2)
# 即得到 1+2 =13
# 1 2
# 13

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-04-09 18:19:02  更:2022-04-09 18:19:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 18:44:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码