python—装饰器

装饰器概念:
把一个函数当作参数传递给一个函数,返回一个替代版的函数
本质上就是一个返回函数的函数
在不改变原函数的基础上,给函数增加功能
python 中装饰器做的事情!它们封装一个函数,并且用这样或者那样的方式来修改它的行为
@ 符号,那只是一个简短的方式来生成一个被装饰的函数

def outer(func):def inner():print('*****')func()return inner@outer
def func():print('have a nice day!')
@outer
def func2():print('hello world')
func()
func2()运行结果:
*****
have a nice day!
*****
hello world

装饰器示例:

import time# 装饰器
def decorator(func):def wrapper():print(time.time())func()return wrapper@decorator  # 调用装饰器
def f1():print('This is a function...')def f2():  # 没有装饰器print('This is a function...')f1()
f2()运行结果:
1560391414.8582878                f1
This is a function...
This is a function...             f2

装饰器实现一个函数计时器

import time
import string
import random
import functoolsli = [random.choice(string.ascii_letters)for i in range(1000)]def timeit(fun):# 问题1:被装饰的函数有返回值的时候怎么办?# 问题2:被装饰的函数如何保留自己的函数名和帮助信息文档?@functools.wraps(fun)def wapper(*args, **kwargs):"""这是一个wapper函数"""# 在函数的执行之前start_time = time.time()# 执行函数res = fun(*args, **kwargs)# 在函数执行之后end_time = time.time()print('运行的时间为:%.6f' % (end_time - start_time))return resreturn wapper@timeit
def con_add():s = ''for i in li:s += (i + '+')print(s)@timeit
def join_add():print('+'.join(li))con_add()
join_add()@timeit
def fun_list(n):"""这是fun_list函数,被timeit装饰"""return [2 * i for i in range(n)]
@timeit
def fun_map(n):"""这是fun_map函数,被timeit装饰"""return list(map(lambda x:x*2,range(n)))# fun_list(5000)
# fun_map(5000)
print(fun_list.__doc__)
print(fun_map.__doc__)
print(fun_list.__name__)
print(fun_map.__name__)

创建装饰器, 要求如下:
1 . 创建add_log装饰器, 被装饰的函数打印日志信息;
2 . 日志格式为: [字符串时间] 函数名: xxx,
运行时间:xxx, 运行返回值结果:xxx

import time
import functools
print(time.ctime())def add_log(func):@functools.wraps(func)def wrapper(*args,**kwargs):start_time = time.time()res = func(*args,**kwargs)end_time = time.time()print('[%s] 函数名:%s,运行时间:%.6f,运行返回值的''结果:%d' %(time.ctime(),func.__name__,end_time-start_time,res))return resreturn wrapper
@add_log
def add(x,y):time.sleep(1)return x+y
add(1,10)

多个装饰器装饰函数,从上到下执行

def decorator_a(fun):def inner_a(*args,**kwargs):print('Get in inner_a')return fun(*args,**kwargs)return inner_adef decorator_b(fun):def inner_b(*args,**kwargs):print('Get in inner_b')return fun(*args,**kwargs)return inner_b@decorator_b
@decorator_a
def f(x):print('Gat in f')return x*2f(1)

多个装饰器的应用场景:
会采用多个装饰器先验证是否登陆成功,再验证登陆权限是否足够
inspect.getcallargs会返回一个字典,

import inspect
import functools
def is_admin(fun):@functools.wraps(fun)def wrapper(*args,**kwargs):# inspect.getcallargs   会返回一个字典,# key值:形参 value:对应的实参数inspect_res = inspect.getcallargs(fun,*args,**kwargs)print('inspect的返回值是:%s' %(inspect_res))if inspect_res.get('name') == 'root':temp = fun(*args,**kwargs)return tempelse:print('not root user,no permisson add user')return wrapper
login_session = ['root','admin','redhat']def is_login(fun):@functools.wraps(fun)def wrapper(*args,**kwargs):if args[0] in login_session:temp = fun(*args,**kwargs)return tempelse:print('Error:%s 没有登陆成功' %(args[0]))return wrapper
@is_login
@is_admin
def add_user(name):print('add user~')
add_user('root')

代参数的装饰器

import functools
import timedef log(kind):def add_log(func):@functools.wraps(func)def wrapper(*args,**kwargs):start_time = time.time()res = func(*args,**kwargs)end_time = time.time()print('<%s>[%s] 函数名:%s,运行时间:%.6f,运行返回值的''结果:%d' %(kind,time.ctime(),func.__name__,end_time-start_time,res))return resreturn wrapperreturn add_log
@log('debug')
def add(x,y):time.sleep(1)return x+y
print(add(1,2))

练习题:
编写装饰器required_types, 条件如下:
1). 当装饰器为@required_types(int,float)确保函数接收到的每一个参数都是int或者float类型;
2). 当装饰器为@required_types(list)确保函数接收到的每一个参数都是list类型;
3). 当装饰器为@required_types(str,int)确保函数接收到的每一个参数都是str或者int类型;
4). 如果参数不满足条件, 打印 TypeError:参数必须为xxxx类型

import functools
def required_types(*kinds):def required_int(fun):@functools.wraps(fun)def wrapper(*args, **kwargs):for i in args:if not isinstance(i, kinds):# print('TypeError:参数必须为',kinds)# breakraise TypeError('参数必须为%s,%s' % kinds)else:res = fun(*args, **kwargs)return resreturn wrapperreturn required_int# @required_types(float, float)
# def add(a, b):
#     return a + b
#
# print(add(1.1, 2.0))
运行结果为:3.1# @required_types(list)
# def add(a, b):
#     return a + b
#
# print(add(1.1, 2.0))
运行结果为:
Traceback (most recent call last):File "/home/kiosk/PycharmProjects/20190523/练习.py", line 65, in <module>print(add(1.1, 2.0))File "/home/kiosk/PycharmProjects/20190523/练习.py", line 42, in wrapperraise TypeError('参数必须为%s,%s' % kinds)
TypeError: not enough arguments for format string

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/542089.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ad18原理图器件批量修改_Altium Designer 15原理图设计基础

Altium Designer 15成为越来越多电子设计开发工程师EDA电路设计软件的首选&#xff0c;在学校学习Altium Designer的也越来较多&#xff0c;像单片机开发学习一样&#xff0c;EDA设计只要学会了&#xff0c;再学其他的设计软件就容易多了。上一节分享了《Altium Designer 15集成…

c++freopen函数_使用示例的C语言中的freopen()函数

cfreopen函数C语言中的freopen()函数 (freopen() function in C) Prototype: 原型&#xff1a; FILE* freopen(const char *str, const char *mode, FILE *stream);Parameters: 参数&#xff1a; const char *str, const char *mode, FILE *streamReturn type: FILE* 返回类型…

python—文件

1 . 文件的基本操作&#xff1a; 文件读取三部曲&#xff1a; 打开操作关闭&#xff08;如果不关闭会占用文件描述符&#xff09; 打开文件&#xff1a; f open(/tmp/passwdd,w)操作文件&#xff1a; 1 . 读操作&#xff1a; f.read()content f.read()print(content) 2 …

基本概念学习(7000)--P2P对等网络

对等网络&#xff0c;即对等计算机网络&#xff0c;是一种在对等者&#xff08;Peer&#xff09;之间分配任务和工作负载的分布式应用架构[1] &#xff0c;是对等计算模型在应用层形成的一种组网或网络形式。“Peer”在英语里有“对等者、伙伴、对端”的意义。因此&#xff0c;…

c语言for循环++_C ++程序使用循环查找数字的幂

c语言for循环Here, we are going to calculate the value of Nth power of a number without using pow function. 在这里&#xff0c;我们将不使用pow函数来计算数字的N 次幂的值 。 The idea is using loop. We will be multiplying a number (initially with value 1) by t…

厦门one_理想ONE真是“500万内最好的车”?

提起罗永浩&#xff0c;不少人还停留在“砸冰箱、造手机”等早期事件。随着网络直播的兴起&#xff0c;罗永浩转战直播带货行业&#xff0c;但老罗毕竟是老罗&#xff0c;雷人语录一点没比以前少。前一段时间&#xff0c;罗永浩在微博中称&#xff1a;“理想ONE是你能在这个价位…

Data Collection

众所周知&#xff0c;计算机领域论文是要以实验为基础的&#xff0c;而实验的原料就是数据。不管是在图像&#xff0c;文字或者语音领域&#xff0c;开源的数据都十分宝贵和重要。这里主要收集各领域的一些常用的公开数据集。 计算机视觉&#xff1a; 【ImageNet】 【Caltech P…

python—os模块、时间模块

os模块 作用&#xff1a;os模块是python标准库中的一个用于访问操作系统功能的模块&#xff0c; os模块提供了其他操作系统接口&#xff0c;可以实现跨平台访问。 使用&#xff1a; 1 . 返回操作系统类型 &#xff1a;os.name 值为&#xff1a;posix 是linux操作系统 值为&…

kotlin键值对数组_Kotlin程序检查数组是否包含给定值

kotlin键值对数组Given an array and an element, we have to check whether array contains the given element or not. 给定一个数组和一个元素&#xff0c;我们必须检查数组是否包含给定的元素。 Example: 例&#xff1a; Input:arr [34, 56, 7, 8, 21, 0, -6]element to…

enter sleep mode黑屏怎么解决_【linux】 不要再暴力关机了,讲讲我最近遇到的问题和完美解决方案...

欢迎关注我的个人公众号&#xff1a;AI蜗牛车前言结束了每天的紧张的工作&#xff0c;这两天真的有些肝。这两天打打字&#xff0c;突然感觉手指头疼起来了&#xff0c;想意识到成天打了十多个小时的键盘&#xff0c; 手指头都疲劳了 之后这两天基本上除了基本的吃睡&#xff…

重复T次的LIS的dp Codeforces Round #323 (Div. 2) D

http://codeforces.com/contest/583/problem/D 原题&#xff1a;You are given an array of positive integers a1, a2, ..., an  T of length n  T. We know that for any i > n it is true that ai  ai - n. Find the length of the longest non-decreasing …

微擎pc 导入前缀_段覆盖前缀| 8086微处理器

微擎pc 导入前缀As we already know that the effective address is calculated by appending the segment registers value and adding up the value of the respective offset. But what if we want to choose some other offset than the assigned one. 众所周知&#xff0…

python—面向对象

面向过程 面向对象&#xff1a; 面向过程&#xff1a;—侧重于怎么做&#xff1f; 1.把完成某一个需求的 所有步骤 从头到尾 逐步实现 2.根据开发要求&#xff0c;将某些功能独立的代码封装成一个又一个函数 3.最后完成的代码&#xff0c;就是顺序的调用不同的函数 特点&#…

5中bug vue_苹果官网出BUG!这些都只要一两百元

近日&#xff0c;有网友在网上反馈称&#xff0c;他发现苹果官网商城出现了BUG&#xff01;众多上千元的产品&#xff0c;BUG价只需一两百元。比如Shure MOTIV MV88 Digital立体声电容式麦克风配件。正常售价1288元&#xff0c;而BUG后的价格是235元。UBTECH Jimu Astrobot Cos…

常用压缩,解压与打包

常用压缩格式&#xff1a; .zip .zg .bz2 .tar.gz .tar.bz2.zip格式压缩zip 压缩文件名 源文件#压缩文件注&#xff1a;压缩文件名写.zip后缀是为了标记该文件的压缩类型&#xff0c;方便管理。注&#xff1a;在压缩时有压缩格式转换&#xff0c;所以当源文件很小时&#xff0c…

css禁用选中文本_使用CSS禁用文本选择突出显示

css禁用选中文本Introduction: 介绍&#xff1a; Texts are the most fundamental elements of any websites or web pages, they form the basis of the web pages or websites because if you don’t write something that you will not be able to present anything. There…

CDN加速实现—varnish

CDN介绍&#xff1a; 1 . 对cdn的理解&#xff1a; CDN的全称是&#xff08;Content Delivery Network&#xff09;&#xff0c;即内容分发网络&#xff1b;加速器&#xff0c;反向代理缓存。CDN系统能够实时的根据网络流量和各节点的连接&#xff0c;负载状况以及到用户的举例…

3dmax如何拆分模型_3dmax制作装饰柜1

大家好&#xff0c;今天我来为大家讲解一下如何利用3dmax制作装饰柜。我们需要制作装饰柜模型&#xff0c;当我们为它添加一个材质后&#xff0c;它就是这样的效果。单击创建&#xff0c;选择图形&#xff0c;对象为样条线&#xff0c;选择矩形在场景中进行创建。单击修改&…

TODO:macOS上ThinkPHP5和Semantic-UI集成

TODO&#xff1a;macOS上ThinkPHP5和Semantic-UI集成1. 全局安装 (on OSX via homebrew)Composer 是 homebrew-php 项目的一部分2. 把Xcode升级到8.1后继续安装Composer3. 使用composer创建TP5项目MWL-Dispatchcomposer create-project topthink/think MWL-Dispatch4. 配置apac…

np.expm1_JavaScript中带有示例的Math.expm1()方法

np.expm1JavaScript | Math.expm1()方法 (JavaScript | Math.expm1() Method) Math operations in JavaScript are handled using functions of math library in JavaScript. In this tutorial on Math.expm1() method, we will learn about the expm1() method and its workin…