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 -闲谈闭包函数与有参无参装饰器,你掌握了吗

一、什么是闭包函数?

在听了Egon老师的讲解后我有了一些见解来跟xdm分享:

闭包函数=名字空间与作用域+函数嵌套+函数对象
‘闭'函数指的该函数是内嵌函数
‘包’函数指的该函数包含对外层函数作用域名字的引用(不是对全局作用域)
注意:内部函数包含对外部作用域而非全局作用域的引用

来为大家举个例子:

x=100
def f1():
    x=1
    def f2():
        print(x)
    return f2


# 可以理解为f2就是被f1包起来的函数,它的内容(如x)是外层函数f1(x=1)所提供而非全局的作用域(x-100)所提供

f=f1()# ==》f=f1的return=》f=f2==》得到的是f2的内存地址
print(f)# ==><function f1.<locals>.f2 at 0x0000022DA470D3A0>
f()#==》f2()==>1

二、无参装饰器

首先大家要明白装饰器就是闭包函数的一种应用场景

那xdm知道-为何要用装饰器吗?

根据开放封闭原则:对修改封闭,对扩展开放

有时大家在做项目时,你写好了一个功能,当你想要为这个功能添加或修改一些功能时,如果不用装饰器,你可能要在原来的功能代码上进行修改,要是每次都要在原来的代码上进行修改,大家会不会觉得太累了呢?特别是你要在别人写的功能代码上进行修改时。而装饰器遵循的开放封闭原则很好的避免了这个问题。

什么是装饰器?

装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。

强调装饰器的原则:

1 不修改被装饰对象的源代码

2 不修改被装饰对象的调用方式

装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能

首先我来跟大家列下无参装饰器的模板:

# 无参装饰器模板

'''def 无参装饰器(func):
    def wrapper(*args,**kwargs):
        res=func(*args,**kwargs)
        return res
    return wrapper
    

@无参装饰器
def 被装饰函数():
    ...
'''

下面我们来用无参装饰器的模板来进行一个小的案例:

import time
def timmer(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        res = func(*args, **kwargs)
        stop = time.time()
        print(stop - start)
        return res

    return wrapper
# 上面者段代码的功能就是计算传进来的函数func运行所需的时间

# 当运行到@装饰器时,不会去运行装饰器下面的函数,调用的是装饰器的函数功能
@timmer#==>index=tmmer(index)
def index(x,y):
     time.sleep(2)
     print('index %s %s'%(x,y))
     return x+y

index(2,3)
# 输出结果为:
# index 2 3
# 2.006439685821533

这就是套用的无参装饰器的模板,但大家想必也很疑惑和好奇,它的原理是什么,下面我将不用装饰器,来实现上面一样的功能和输出结果

def index(x,y):
    time.sleep(2)
    print('index %s %s'%(x,y))
    return x+y

def outter(func):
    def wrapper(*args,**kwargs):
        start=time.time()
        res=func(*args,**kwargs)
        stop=time.time()
        print(stop-start)
        return res
    return wrapper

index=outter(index)
# 将index函数作为参数传入outter(func)
# ==》将outter的返回值传给变量index(注意区分,第一个index和第二个index)
# ==》index=wrapper==》index指向的是wrapper的内存地址而非index函数的内存地址

index(2,3)# ==》其实运行的是wrapper(2,3)
# start=time.time() 记录运行func()开始前的时间
# res=func(*args,**kwargs)==>res=index(2,3)==>index是传进来的参数,(2,3)是wrapper(2,3)的参数
# stop=time.time() 记录func()结束后的时间
# print(stop-start)打印时间差即函数运行的时间
# return res 返回调用index()return的结果 ,若没有return 则默认为None

print('====>',index(2,5))

想必大家应该也明白了其中的原理,有参的装饰器运行的原理也和上面的无参装饰器的原理差不多。当有多个装饰器装饰一个函数时,从最下面的装饰器开始调用

def outter1(func1): #func1=wrapper2的内存地址
    print('加载了outter1')
    def wrapper1(*args,**kwargs):
        print('执行了wrapper1')
        res1=func1(*args,**kwargs)
        return res1
    return wrapper1

def outter2(func2): #func2=wrapper3的内存地址
    print('加载了outter2')
    def wrapper2(*args,**kwargs):
        print('执行了wrapper2')
        res2=func2(*args,**kwargs)
        return res2
    return wrapper2

def outter3(func3): # func3=最原始的那个index的内存地址
    print('加载了outter3')
    def wrapper3(*args,**kwargs):
        print('执行了wrapper3')
        res3=func3(*args,**kwargs)
        return res3
    return wrapper3



@outter1 # outter1(wrapper2的内存地址)======>index=wrapper1的内存地址
@outter2 # outter2(wrapper3的内存地址)======>wrapper2的内存地址
@outter3 # outter3(最原始的那个index的内存地址)===>wrapper3的内存地址
def index():
    print('from index')

print('======================================================')
index()

# 输出结过如下:
’‘’
加载了outter3
加载了outter2
加载了outter1
======================================================
执行了wrapper1
执行了wrapper2
执行了wrapper3
from index
‘’‘

三、有参装饰器

有参装饰器模板
'''def 有参装饰器(参数):
    def outter(func):
        def wrapper(*args,**kwargs):
            res=func(*args,**kwargs)
            return res
        return wrapper
    return outter

@有参装饰器(参数)
def 被装饰函数():
    ...
'''

原理无非和无参装饰器一样,就不为大家详细介绍啦,有兴趣的兄弟可以课下自己套用模板试一下,不会的可以私信我欧,希望大家喜欢,一起进步!要是喜欢的话欢迎大家来关注我欧~有不足的地方欢迎大家指出,会继续为xdm更新的

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-11-16 18:47:09  更:2021-11-16 18:47:16 
 
开发: 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年12日历 -2024/12/31 4:56:51-

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