python函数知识七 闭包、装饰器一(入门)、装饰器二(进阶)

时间:2023-02-18 18:42:14

21.闭包

  1. 闭包:在嵌套函数内,使用非全局变量(且不使用本层变量)
  2. 闭包的作用:1.保证数据的安全性(纯洁度)。2.装饰器使用
  3. .__closure__判断是否是闭包
def func():
a = 1
def foo():
print(a)
return foo
ret = func()
ret()
#例子
def func():
avg_lst = []
def foo(pirce):
avg_lst.append(pirce)
avg = sum(avg_lst) / len(avg_lst)
return avg
return foo
ret = func()
print(ret(1500))
print(ret(1600))
print(ret.__closure__)#结果:(<cell at 0x000002095400B558: list object at 0x00000209540A5B48>,)证明是闭包
print(func.__closure__)#结果:None,不是闭包 print(ret.__code__.co_freevars)#获取的是*变量
print(ret.__code__.co_varnames)#获取的是局部变量

22.装饰器一(入门)

1.一个装饰器装饰多个函数

开放封闭原则:扩展是开放的(增加新功能),源码是封闭的(修改已经实现的功能)

作用:在不改变源代码及调用方式的基础下额外增加新功能。

装饰器:用来装饰的工具

2.版一:
import time
start_time = time.time
def func():
time.sleep(2)#睡眠s模拟网络延时
print("我要飞")
func()
print(time.time - start_time)
#改变了源代码
3.版二:
def times(f):
start_time = time.time()
f()
print(time.time() - start_time)
def foo():
time.sleep(3)
print("我飞的比你高")
#times(foo)#改变了调用方式
s = foo
foo = times
foo(s)#不改变调用方式
4.版三:(low版装饰器)
def times(f):
def inner():
start_time = time.time()
f()
print(time.time() - start_time)
return inner
def foo():
time.sleep(3)
print("我飞的比你高")
foo = times(foo)
foo()
5.版四:
def wrapper(f):
def inner(a):
start_time = time.time()
f(a)
print(time.time() - start_time)
return inner#切记不加括号 def func(a):
print(f"{a}你不行")
func = wrapper(func)
func("alex")
#传输多个数据,用*args,**kwargs
6.版五(标准版装饰器):

@wrapper#语法糖:必须放在要装饰的函数的正上方

def wrapper(f):#f是要被装饰的函数名
def inner(*args,**kwargs):
"被装饰前"
start_time = time.time()
ret = f(*args,**kwargs)
print(time.time() - start_time)
"被装饰后"
return ret
return inner#切记不加括号
@wrapper#语法糖 -->func = wrapper(func)
def func(*args,**kwargs):
print(f"{a}你不行")
return "我可以返回了"
#func = wrapper(func)#有语法糖不用多次赋值
func("alex")

23.装饰器二(进阶)

1.有参装饰器:

​ 有参装饰器:在基础装饰器的基础上再套一层函数

#有参装饰器实现登陆验证
msg = """
QQ
微信
抖音
请输入您要登录的的app:
"""
chose = input(msg).upper()
dict_flag = {'username':None,'flag':False}
def auth(a):
def wrapper(f):
def inner(*args,**kwargs):
if dic_flag['flag']:
fun(*args,**kwargs)
else:
if argv =="QQ":
print("欢迎登陆QQ")
user = intput("user:")
pwd = input("passwd:")
if user == "alex" and pwd == "alex123":
dict_flag["flag"] = True
dict_flag["username"] = user
foo(*args,**kwargs) else:
print("用户名或密码错误!")
return inner
return wrapper
@auth(chose)
"""
语法糖拆分:
wrapper = auth(chose)
foo = wrapper(foo)
"""
def foo():
print("这是被装饰的函数")
foo()

2.多个装饰器装饰一个函数:

​ 当被装饰的函数正上方有多个装饰器,先执行里被装饰函数最近的装饰器(小技巧:进入装饰器,从上往下,走到最后一个装饰器,执行被装饰的函数,退出装饰器从下往上)

def wrapper1(f):
def inner1(*args,**kwargs):
print("这是第一个装饰器开始")
f(*args,**kwargs)
print("这是第一个装饰器结束")
return
return inner1 def wrapper2(f):
def inner2(*args,**kwargs):
print("这是第二个装饰器开始")
f(*args,**kwargs)
print("这是第二个装饰器结束")
return
return inner2 @wrapper1
@wrapper2
"""
两个语法糖等价于:
foo = wrapper2(foo)#foo == inner2
foo = wrapper1(foo)#foo = wrapper(inner2),foo == inner1
foo()#-->inner1()
"""
def foo():
print("这是被装饰的函数")
foo()
'''
结果:
这是第一个装饰器开始
这是第二个装饰器开始
这是被装饰的函数
这是第二个装饰器结束
这是第一个装饰器结束
'''

python函数知识七 闭包、装饰器一(入门)、装饰器二(进阶)的更多相关文章

  1. python 函数名 、闭包 装饰器 day13

    1,函数名的使用. 函数名是函数的名字,本质就是变量,特殊的变量.函数名()加括号就是执行此函数. 1,单独打印函数名就是此函数的内存地址. def func1(): print(555) print ...

  2. python函数作用域,闭包,装饰器

    第一:函数作用域: L:local 函数内部作用域 E:enclosing       函数内部与内嵌函数之间(闭包) G:global            全局作用域 B:build_in    ...

  3. python函数对象和闭包

    关于函数对象和闭包 闭包(closure)是函数式编程的重要的语法结构.不同的语言实现闭包的方式不同.Python以函数对象为基础,为闭包这一语法结构提供支持的 (我们在特殊方法与多范式中,已经多次看 ...

  4. python函数知识

    一.三目运算 也叫三元运算,例如result=x if x<y else y 二.集合(set) 返回主页集合(set):把不同的元素组成一起形成集合,是python基本的数据类型.集合元素(s ...

  5. Python函数——命名空间与闭包

    前言 执行以下代码 def my_test(): x = 1 y = x+1 print(x) >> Traceback (most recent call last): File &qu ...

  6. python基础知识七

    我们会使用raw_input和print语句来完成这些功能. 对于输出,也可以使用多种多样的str(字符串)类. 例如使用rjust方法来得到一个按一定宽度右对齐的字符串. 可以通过创建一个file类 ...

  7. python 函数名,闭包

    1.函数名字的应用 函数名是什么? 函数名是函数的名字,本质:变量,特殊变量 函数名+() ———>执行此函数: 2.函数名的赋值: def func2(): print(44) f = fun ...

  8. python函数知识四 迭代器、生成器

    15.迭代器:工具 1.可迭代对象: ​ 官方声明,只要具有__iter__方法的就是可迭代对象 list,dict,str,set,tuple -- 可迭代对象,使用灵活 #方法一: list.__ ...

  9. python函数知识五 推导式和内置函数一(了解)

    17.推导式: 推导式:将for循环多行变成一行 list推导式:[] #普通模式 print([i for i in range(20)]) #循环模式 #[变量 for i in range(20 ...

随机推荐

  1. NOI 题库 6266

    6266  取石子游戏 描述 有两堆石子,两个人轮流去取.每次取的时候,只能从较多的那堆石子里取,并且取的数目必须是较少的那堆石子数目的整数倍.最后谁能够把一堆石子取空谁就算赢. 比如初始的时候两堆石 ...

  2. 找出单链表的倒数第K个(从1开始计数)结点的值

    typedef struct Link { int data; struct Link* next; }NODE,*pNODE; NODE *searchK(NODE *phead, int k) { ...

  3. poj1142&period;Smith Number(数学推导)

    Smith Number Time Limit: 1 Sec  Memory Limit: 64 MB Submit: 825  Solved: 366 Description While skimm ...

  4. div&plus;css的前端工程师的价值体现在哪些方面?

    个人认为前端工程师正慢慢演变为产品工程师.wap app, 响应性UI等以html5技术为基础的开发将成为前端工程师的主要工作内容,解决产品跨平台跨设备的实现问题.Javascript, HTML, ...

  5. Qt 解压&sol;压缩文件

    很久没有在博客园写随笔了,今天项目需要解压和压缩文件,所以去了解哈. 参考的是大神的代码:https://yq.aliyun.com/articles/24428. 使用的是 QuaZIP类. 类 说 ...

  6. VB6之阴影图层

    要是能创建半透明的刷子就好了,就不必像这样以图层的方式实现透明阴影效果. 代码: 'code by lichmama@cnblogs.com '绘制阴影图层 Private Declare Funct ...

  7. Akka(39): Http:File streaming-文件交换

    所谓文件交换指的是Http协议中服务端和客户端之间文件的上传和下载.Akka-http作为一种系统集成工具应该具备高效率的数据交换方式包括文件交换和数据库表行的上传下载.Akka-http的数据交换模 ...

  8. Redis笔记1-redis的搭建和使用

    1.   Redis的安装 1.1. Redis的安装 Redis是c语言开发的. 安装redis需要c语言的编译环境.如果没有gcc需要在线安装.yum install gcc-c++ 安装步骤: ...

  9. Mysql 函数使用记录&lpar;二&rpar;——ELT&lpar;&rpar;、FIELD&lpar;&rpar;、IFNULL&lpar;&rpar;

    昨天在对一业务修改的过程中想到用DECODE()来实现效果,转眼发现目前使用的是Mysql库,经过查阅,最终用ELT().FIELD().IFNULL()函数来实现需求.现对其做一个记录. 语法: E ...

  10. Redmine部署到Windows Azure

    有幸,今天可以尝试将Redmine部署到Windows Azure中,记下点滴,方便大家查阅 步骤一:Windows Azure中安装Ubuntu VM 遇到的问题,创建VM时会提示云服务.云存储订阅 ...