Python学习之路基础篇--11-12Python基础,函数的装饰器
对于装饰器来说,就是在不改变函数的调用的情况下,对函数的前后增加了些许功能,这完全符合函数的 开放封闭 原则。装饰器的本质 其实就是一个闭包函数。
这是一个装饰器的步骤图
def wrapper(func): #
def inner(*args,**kwargs): #
ret = func(*args,**kwargs) #
return ret #
return inner # @wrapper #shopping = wrappers(shooping) # 1 --shopping = innner
def shopping(num): #
print(num) #
return 1 # print(shopping(5)) #
这样你调 shopping 时, 真实情况是你在调用 inner 函数。如果 你想打印其函数名时打印的其实是 innner 函数。
from functools import wraps
def wrapper(func): #
@wraps(func)
def inner(*args,**kwargs): #
ret = func(*args,**kwargs) #
return ret #
return inner # @wrapper #shopping = wrappers(shooping) # 1 --shopping = innner
def shopping(num): #
print(num) #
return 1 # print(shopping(5)) #
print(shopping.__name__) #以字符串的形式获取到函数名
print(shopping.__doc__) #以字符串的形式获取到函数注释
如果用内置的模块,wraps ,就可以轻松解决这个问题,使得所有的还和以前一样,其中wraps(),中要传入参数,参数应该与外层装饰器的形参一致。
对于装饰器,如果你想取消个这装饰器的功能,现在给出的方法就只能是在装饰的外面在套一个装饰器,并设置一个定位符(一个全局变量)来控制其是否执行:
control = True
def outer(flag):
def wrapper(func):
def inner(*args,**kwargs):
if flag:
print('函数执行前')
ret = func(*args,**kwargs)
print('函数执行后')
return ret
else:
ret = func(*args, **kwargs)
return inner
return wrapper @outer(control)# shoping = outer(shopping) = wapper(shoping) = inner(shopping) 只是要多一个参数进行判断
def shopping(num):
print(num)
return 1 shopping(5)
多个装饰器进行嵌套,装饰器的糖的运行是,就近原则,离函数最近的糖先运行
def wrapper1(func): #func--shopping
def inner(*args,**kwargs):
print('000函数执行前')
ret = func(*args,**kwargs)
print('000函数执行后')
return ret
return inner def wrapper2(func): #func--inner1
def inner(*args,**kwargs):
print('111函数执行前')
ret = func(*args,**kwargs) #这里的调用其实是使用 inner1() 函数
print('111函数执行后')
return ret
return inner @wrapper2
@wrapper1
def shopping(num):
print(num)
return 1 shopping(5)
'''
111函数执行前
000函数执行前
5
000函数执行后
111函数执行后
'''
来个作业
# 在12 天作业 编写装饰器,为多个函数加上认证功能(用户的账号来源于文件),
# 要求登入一次成功,后续的函数都无需再输入用户和密码
def wrapper(func):
def inner(*args, **kwargs):
with open('ver', mode='r+',encoding='utf-8')as f:
flag = f.read()
if flag:
verification = input('>>>').strip()
if verification == 'eli123':
# f.seek(0)
f.truncate(0,)
ret = func(*args, **kwargs)
return ret
else:
ret = func(*args, **kwargs)
return ret
return inner @wrapper
def buy(num):
print('买了{}个包子'.format(num))
@wrapper
def eat(num):
print('吃了{}个包子'.format(num))
with open('ver',mode='w',encoding='utf-8') as f:
f.write('aaa')
buy(3)
eat(2)
这里利用了一个文件,在进行函数前,生成内容,然后文件中有内容时,要求验证 验证码,然后删除,方便第二次的验证。
# 2.编写装饰器,为多个函数加上记录调用功能,要求每次调用函数都将被调用的函数名称写入文件
from functools import wraps
def wrapper(func):
wraps(func)
def inner(*args, **kwargs):
with open('record',mode='a',encoding='utf-8') as f:
f.write(func.__name__ + '\n')
ret = func(*args, **kwargs)
return ret
return inner @wrapper
def buy(num):
print('买了{}个包子'.format(num))
@wrapper
def eat(num):
print('吃了{}个包子'.format(num)) buy(3)
eat(2)
与第一题相比,确实比较容易一点(之后学到时间模块,可以加入时间模块的)
Python学习之路基础篇--11-12Python基础,函数的装饰器的更多相关文章
- python学习之路入门篇
本文是up学习python过程中遇到的一些问题及总结归纳,本小节是入门篇. python基本语法 循环.分支不多赘述. 模块:一个.py文件就是一个模块. 文件和异常 模式 含义解释 “r” 读模式 ...
- python学习之路 八 :面向对象编程基础
本节重点 了解面向对象.面向过程的区别 掌握什么是类,什么是对象 掌握如何定义及使用类和对象 了解类与对象间的关系 掌握类属性和实例属性 掌握绑定方法 一.编程范式 编程即写程序or写代码 ...
- Python3基础(4)匿名函数、装饰器、生成器、迭代器、内置函数、json&pickle序列化、软件目录开发规范、不同目录间模块调用
---------------个人学习笔记--------------- ----------------本文作者吴疆-------------- ------点击此处链接至博客园原文------ 1 ...
- Python 学习之路 (一):基础
数据类型和变量 整数 在Python3中,整数可以处理任意大小的整数,不分长整型和整型, 十六进制用0x开头或者H结尾表示:0x2af ,2afH 用函数 int() 来转换字符串中的数字,里面不能包 ...
- python学习之路---day25( 网络编程基础和初识socket)
基本网络知识和初识socket一:基本知识 网线:传输电信号 集线器:将所有连接到集线器的网络设备连通起来 交换机: 升级版的集线器 网卡:接受电信号 MAC地址:物理地址: 8C-88-4B-88- ...
- python -- 返回函数、匿名函数、装饰器
返回函数 高阶函数的参数可以是函数,那么其返回值也可以是函数. 闭包 对于高阶函数,内部函数可以引用外部函数的参数和局部变量.当调用外部函数返回内部函数时,相关参数和变量都保存在返回的函数(即内部函数 ...
- Python学习之路【第一篇】-Python简介和基础入门
1.Python简介 1.1 Python是什么 相信混迹IT界的很多朋友都知道,Python是近年来最火的一个热点,没有之一.从性质上来讲它和我们熟知的C.java.php等没有什么本质的区别,也是 ...
- python学习之路基础篇(第四篇)
一.课程内容回顾 1.python基础 2.基本数据类型 (str|list|dict|tuple) 3.将字符串“老男人”转换成utf-8 s = "老男人" ret = by ...
- python学习之路-day2-pyth基础2
一. 模块初识 Python的强大之处在于他有非常丰富和强大的标准库和第三方库,第三方库存放位置:site-packages sys模块简介 导入模块 import sys 3 sys模 ...
- Python学习之路-Day1-Python基础
学习python的过程: 在茫茫的编程语言中我选择了python,因为感觉python很强大,能用到很多领域.我自己也学过一些编程语言,比如:C,java,php,html,css等.但是我感觉自己都 ...
随机推荐
- [数]青蛙的约会&Strange function
拓展欧几里得:求导&二分 POJ-1061 拓展欧几里得的应用,需要开long long 第一次做这个题的时候进行了毫无用处的找公式(?),是个现在的我看不懂的迷之思路. 第二发的时候还是不明 ...
- Oracle 11g OGG mgr定期清理tail 文件
OGG mgr定期清理tail 文件 2018-06-11 11:58 440 0 原创 GoldenGate 本文链接:https://www.cndba.cn/leo1990/article/28 ...
- Object.prototype.toString.call() 、 instanceof 以及 Array.isArray()判断数组的方法的优缺点
1. Object.prototype.toString.call() 每一个继承 Object 的对象都有 toString 方法,如果 toString 方法没有重写的话,会返回 [Object ...
- .net正则匹配
char[] weixin = txtweixinhao.Text.Trim().ToCharArray(); for (int i = 0; i < weixin.Length; i++) i ...
- mybatis 报The content of elements must consist of well-formed character data or markup. 语法格式错误
最近在写sql的时候 同时使用到了 >= 和 <= 之前只使用一个的时候 没有什么问题,今天同时使用到了两个,结果xml出现了The content of elements must co ...
- css实现标题左右横线
最近用到了记录一下 页面 <div class="subtitle"> 马上邀请好友得奖励 </div> 样式 .subtitle { position: ...
- Hello1 web
<?xml version="1.0" encoding="UTF-8"?> xml版本,指定编码格式 <web-app versio ...
- php 多维数组 array sort 排序 :array_multisort
1.参考链接: php简单实现多维数组排序的方法 参考二: 这个链接很好,可以直接看这个:PHP array_multisort—对多个数组或多维数组进行排序 2.案例一: //13: 最佳: pub ...
- python爬取post请求Reque Payload的json数据
import requests,json url = "https://www.yijiupi.com/v31/Product/ListProduct" headers = { ' ...
- Flutter不完全安裝指南(AndroidStudio集成)
Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面.真心無力吐槽這些所谓的中文站以及社区的文档,整理一下安装流程吧. 本人是android开发,基于此基础上 ...