python闭包和装饰器

news/2024/12/23 4:56:12/

目录

一、闭包

1.简单演示

2.内函数修改外函数变量问题

二、装饰器

1.基础使用

2.通用装饰器

3.多个修饰器引用

4.装饰器传参

三、类装饰器

1.callable()和__call__

2.类装饰器的简单使用

结语


一、闭包

1.简单演示

条件

在函数嵌套(函数里面在定义函数)的前提下

内部函数使用了外部函数的变量(还包括外部函数的参数)

外部函数返回了内部函数

def outer():n = 1#内部定义def inner():#使用外部变量print(n)#返回内部函数    return innerret = outer()
print(ret)

def Person(name):def say(msg):print(name+"Say:  "+msg)return saytom = Person('tom')
jack = Person('jack')
tom('你好')
jack('早上好')

2.内函数修改外函数变量问题

真常来说内部函数只有对外部函数访问的权利

def outer():n = 1def inner():n += 10print(n)print(n)return innerfunc = outer()
func()

需要修饰符

def outer():n = 1def inner():nonlocal nn += 10print(n)print(n)return innerfunc = outer()
func()

需要用nolocal


二、装饰器

1.基础使用

特点:

不修改已有函数的源代码

不修改已有函数的调用方法

给已有函数增加额外的功能

他的本质就是一个闭包函数

我们编辑一个计算函数用时功能的程序

import timedef for1():for i in range(10000000):i +=1print(i)def start(func):def inner():s = time.time()func()e = time.time()print("用时:  ",e-s)return innerfunc = start(for1)
func()

用装饰器来写

import timedef start(func):def inner():s = time.time()func()e = time.time()print("用时:  ",e-s)return inner@start
def for1():for i in range(10000000):i +=1print(i)for1()

由此可见装饰器就是一种语法糖

注意:装饰器这里一定要有参数

2.通用装饰器

参数问题

import timedef start(func):def inner():s = time.time()func()e = time.time()print("用时:  ",e-s)return inner@start
def for1(a):for i in range(a):i +=1print(i)for1(10000000000000000)

总结一下可能有的四种状态

#无参数,无返回值
def outer1(func):def inner():print("装饰1.。。")func()print("装饰2.。。")return inner@outer1
def show1():print("show1....")show1()print("________________________")# 有参数,无返回值
def outer2(func):def inner(msg):print("装饰1.。。")func(msg)print("装饰2.。。")return inner@outer2
def show2(msg):print("show2....",msg)show2("python")print("________________________")# 无参数,有返回值
def outer3(func):def inner():print("装饰1.。。")ret = func()print("装饰2.。。")return retreturn inner@outer3
def show3():return "shoe3....."print(show3()+"Nihao")print("________________________")# 有参数,有返回值
def outer4(func):def inner(msg):print("装饰1.。。")ret = func(msg)print("装饰2.。。")return retreturn inner@outer4
def show4(msg):return "shoe3....." +msgprint(show4("python4    ")+"Nihao")

我们需要一个通用的修饰器

def outer(func):def inner(*args,**kwargs):print("装饰1.。。")ret = func(*args,**kwargs)print("装饰2.。。")return retreturn inner
#无参数,无返回值
@outer
def show1():print("show1....")show1()print("________________________")# 有参数,无返回值
@outer
def show2(msg):print("show2....",msg)show2("python")print("________________________")# 无参数,有返回值
@outer
def show3():return "shoe3....."print(show3()+"Nihao")print("________________________")# 有参数,有返回值
@outer
def show4(msg):return "shoe3....." +msgprint(show4("python4    ")+"Nihao")

3.多个修饰器引用

def wrapper_div(func):def inner(*args,**kwargs):return "<div>" + func(*args,**kwargs) + '</div>'return innerdef wrapper_p(func):def inner(*args,**kwargs):return "<p>" + func(*args,**kwargs) + '</p>'return inner@wrapper_p
@wrapper_div
def show():return "show inner "print(show())

执行流程

4.装饰器传参

需要多层函数嵌套来完成

def set_a(msg):def set_f(func):def inner():print("装饰内容: "+msg)func()return innerreturn set_f@set_a("你好")
def show():print("show....")show()


三、类装饰器

1.callable()和__call__


def show():print("show")#这个函数用来测试参数是否是可以调用对象
print(callable(show))
print(callable(1))
print(callable("aa"))class P():#当一个类中实现了__call__函数#那么这个类的实例对象就变成了可调用对象,也就是说,实例对象后面可以加()def __call__(self, *args, **kwargs):print("Call run")
tom = P()
print(callable(tom))tom()

其实也就是说,类本来是不可调用的对象,但是装饰器需要是可调用对象,所以只需要了解这点我们就可以使用了

2.类装饰器的简单使用

class Wra():def __init__(self,func):self.func = funcdef __call__(self, *args, **kwargs):print("装饰")self.func()@Wra
def show():print("show...")
show()


结语

这是最后几篇了,接下来更新Linux云计算方面的博客,大家👍啊!


http://www.ppmy.cn/news/563666.html

相关文章

沧州市新华区小赵庄乡社工站幸福院护蕾驿站微项目启动

烈日炎炎&#xff0c;难抵群众热情。6月16日上午&#xff0c;小赵庄乡社工站在蔡庄子社区开展社工站微项目启动仪式暨助老文艺展演活动。市民政局慈善社工科科长罗向凯&#xff0c;新华区民政局局长李瑞勇&#xff0c;新华区小赵庄乡书记徐晋等人出席本次活动。 社工站护蕾驿站…

jpcsp源码解读9:指令的抽象描述与指令的译码

本文尝试说明jpcsp中译码器单元的实现方式。 / 首先是对指令的一个抽象描述&#xff0c;Instruction类&#xff1a; public static abstract class Instruction / java科普&#xff1a; 注意这是一个抽象类&#xff0c;不可以被实例化。只有在其某个子类中实现该抽象类中…

用Lucene的SpellChecker实现Google的“您是不是要找”功能

引言 很多人在使用搜索引擎的时候&#xff0c;会出于各种原因&#xff0c;拼错想要搜索的关键字&#xff0c;比如键盘有问题&#xff08;某个按键坏了&#xff09;、不熟悉国际名称&#xff08;弗洛伊德的全名 Sigmund Freud&#xff09;、不小心写错字母&#xff08;Sinpsons…

wang----- 用Java实现Google的“您是不是要找”功能

文章来源&#xff1a;http://blog.csdn.net/haydenwang8287/article/details/5777112 引言 很多人在使用搜索引擎的时候&#xff0c;会出于各种原因&#xff0c;拼错想要搜索的关键字&#xff0c;比如键盘有问题&#xff08;某个按键坏了&#xff09;、不熟悉国际名称&#xff…

用Java实现Google的“您是不是要找”功能

引言 很多人在使用搜索引擎的时候&#xff0c;会出于各种原因&#xff0c;拼错想要搜索的关键字&#xff0c;比如键盘有问题&#xff08;某个按键坏了&#xff09;、不熟悉国际名称&#xff08;弗洛伊德的全名Sigmund Freud&#xff09;、不小心写错字母&#xff08;Sinpsons&a…

algodoo是什么意思_�教学创新-中国大学mooc-试题题目及答案

请教&#xff1a;计算机等级考试二级公共基础知识练习题(1)第2大题第11小题如何解答&#xff1f; 关于网站sql和js的攻击方式的具体过程 请教&#xff1a;2011年会计从业考试《会计基础》全真模拟试卷(1)第2大题第10小题如何解答&#xff1f; C语言 malloc 有乱码 dev c&#x…

psp模拟java_PSP模拟器 JAVA环境搭建问题:

展开全部 jpcsp-windows-x86 2. start-windows-x86.bat 内如如下&#xff1a;62616964757a686964616fe78988e69d8331333335336434 echo off rem CD to the path of the command line, this is required when running as an administrator cd /D "%~dp0" set PATH%PA…

linux ppsspp速度,PPSSPP模拟器详细使用技巧

PPSSPP模拟器是一款国内非常优秀流行的专业psp模拟器,PPSSPP模拟器虽然出现较晚,但是其拥有比jpcsp更加完善的功能以及更加快速的模拟速度,PPSSPP模拟器超越平台限制的免费游戏模拟器它支持Windows、Linux、iOS、Android等系统,用户通过PPSSPP模拟器能够回味很多经典有趣的…