Python高级特性之闭包与装饰器实例详解
作者:HMMHMH 发布时间:2021-09-19 03:17:25
本文实例讲述了Python高级特性之闭包与装饰器。分享给大家供大家参考,具体如下:
闭包
1.函数参数:
(1)函数名存放的是函数的地址
(2)函数名()存放的是函数内的代码
(3)函数名只是函数代码空间的引用,当函数名赋值给一个对象的时候,就是引用传递
def func01():
print("func01 is show")
test = func01
print(func01)
print(test)
test()
结果:
2.闭包:
(1)内层函数可以访问外层函数变量
(2)闭包就是一个嵌套定义的函数,在外层运行时才开始内层函数的定义,然后将内部函数的引用传递函数外的对象(闭包外层函数的返回值为内层函数名)
(3)内部函数和使用的外部函数提供的变量构成的整体称为闭包
def func_out(rate):
def func_in(money):
print(rate * money)
return func_in
usa_money = func_out(0.7)
usa_money(100)
usa_money(200)
执行结果:
装饰器
装饰器就是在不改变函数的原有代码的前提下 给函数添加新的功能,装饰器一般是一个闭包。
1.装饰器:
# 在不改变函数的原有代码的前提下 给函数添加新的功能
def func_out(func):
def func_in():
print("验证")
func()
return func_in
@func_out
def login():
print("登录")
# 有装饰器 装饰器下面正好是一个函数
# login = func_out(login) 重点
login()
如果@func_out装饰器下刚好是一个login函数,会执行:
login = func_out(login)
所以会直接执行func_out内的代码,func为原login,即指向原login函数的地址空间并且返回内层函数名,即:
login = func_out(login) = func_in
所以login()的执行结果为func_in(),即:
print('验证')
func() # func指原login函数的地址
就实现了不改变原函数的情况下给函数添加新功能
执行结果:
2.装饰有返回指函数:
def func_out(func):
def func_in():
# ret = func()
# def login():
# return 100
return func()
return func_in
@func_out
def login():
return 100
# login() ==> func_in()
# func ==> 原始的login
f = login()
print(f)
3.装饰有参数函数:
def func_out(func):
def func_in(a):
func(a)
return func_in
@func_out
def login(a):
print(a)
# login() ==> func_in()
# func ==> 原始的login
login(10)
4.装饰器通用版:
def func_out(func):
def func_in(*args,**kwargs):
return func(*args,**kwargs)
return func_in
@func_out
def login(*args,**kwargs):
print(args)
print(kwargs)
# login() ==> func_in()
# func ==> 原始的login
login(10,20,age = "17",name="123")
5.类装饰器:
class Foo(object):
def __init__(self, func):
self.func = func
def __call__(self):
print("验证")
self.func()
@Foo
def login():
print("登录")
# login = Foo(login)
login()
6.多装饰器:
def func_out01(func01):
print("func_out01 is show")
def func_in01():
print("func_in01 is show")
func01()
return func_in01
def func_out02(func02):
print("func_out02 is show")
def func_in02():
print("func_in02 is show")
func02()
return func_in02
@func_out02 # login = func_out02(login)
@func_out01 # login = func_out01(login)
def login():
print("login is show")
login()
执行结果:
因为@闭包名下为函数时才会实现装饰器,所以func_out1会先装饰函数,func_out2会后装饰函数,所以外层函数先执行func_out1,后执行func_out2;因为func_out1先装饰函数,func_out2后装饰函数,所以func_out1装饰后,原函数为先输出func_in1内的语句,再输出原login,然后func_out2装饰后,执行顺序为先输出func_in2的语句,再输出装饰后的login函数,即:func_in2——func_in1——login。
7.给装饰器传递函数:
def route(参数):
print(参数)
def func_out(func):
def func_in():
func()
return func_in
return func_out
@route(参数)
def index():
return "index is show"
希望本文所述对大家Python程序设计有所帮助。
来源:https://blog.csdn.net/zsh142537/article/details/82685087
猜你喜欢
- php遍历目录和文件的场景在很多时候都能用到,遍历目录方法的方法有好几种,那么应该使用
- 首次安装、运行MySQL时,你可能会遇到一些错误,使MySQL服务器不能启动。本节的目的是帮助你诊断并纠正这些错误。解决服务器问题时你的第一
- 之前介绍过python开发工具Jupyter的使用,今天继续讲解python的数据类型,python中有整型、浮点型、字符串、布尔类型,我们
- 本文实例讲述了php替换字符串中间字符为省略号的方法。分享给大家供大家参考。具体分析如下:对于一个长字符串,如果你只希望用户看到头尾的部分内
- 空白双边距是一个极容易误解的CSS特性.它不是CSS的bug,但如果我们一旦误解,将会给你带来很多麻烦.先看如下demo代码:<!do
- 如果独自放着jQuery做事,它绝对做得很好,但jQuery充许与其他库共存在,有些事就防不胜防了。看下面代码data :func
- 只添加了一些自己想到的常用的功能,欢迎大家补充添加自己的好的思路. 通用的正则和方法可以写在RegExpObj中,
- 继续Mootools常用方法扩展,依然还是String类的扩展。方法:unescapseHTML说明:这个上次忘了,和escapseHTML
- 以前在工作中遇到一个问题,当表单发送的数据量很大时,就会报错。查阅MSDN了解到,原因是微软对用Request.Form()可接收的最大数据
- 本文实例讲述了PHP日志LOG类定义与用法。分享给大家供大家参考,具体如下:<?php/*** PHP log 类 */class C
- 下面代码写的是js验证检查输入的字符是否是全角的函数:效果演示:<script> function i
- 字符串Go语言中的字符串以原生数据类型出现。 Go 语言里的字符串的内部实现使用UTF-8编码。 字符串的值为双引号(")中的内容
- 今天突然想起这个问题, 就好好搜索整理一下,不过在开始归纳之前,请先来一起做做这个小实验:忽略一切实际的外在情况, 你看了下面的按钮,第一本
- CSS网页布局应该避免滥用div元素一直是我们倡导的,以合适的HTML标签组织文档是CSS网页布局的基础。页面中div与span元素的使用是
- <div class=”A” style=”position:relative;”>A 
- 自去年以来,我们正在开发区块链(Blockchain)业务。最近使用过Ethereum并使用PHP,所以我想我们应该聊聊这个话题。这里有个前
- 1. 用Dreamweaver 4.0轻松设计会自动弹性调整的网页 首先需要保证的是你的页面内容采用了表格的格式,然后打开你要编辑的页面,按
- <% If Err.Number <> 0 Th
- MySQL是中小型网站普遍使用的数据库之一,然而,很多人并不清楚MySQL到底能支持多大的数据量,再加上某些国内CMS厂商把数据承载量的责任
- 也许还有朋友不太清楚DOMContentLoaded这个事件。简单的说,这个事件就是要在大多数情况下去替代window.onload事件,因