装饰器python与python装饰器
n、迭代,迭代器,生成器,详解传送门:
https://blog.csdn.net/weixin_54217632/article/details/117674316
n.1、python 闭包和装饰器详解
https://www.cnblogs.com/yssjun/p/9887239.html
https://www.cnblogs.com/sweet-i/p/11177063.html
https://blog.csdn.net/u013380694/article/details/90019571?utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromMachineLearnPai2~default-1.base&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromMachineLearnPai2~default-1.base
# nonlocal 与 global 的方法# nonlocal 的用法例子
# 函数嵌套函数的时候,用到。
# nonlocal关键字用来在函数或其他作用域中使用外层(非全局)变量。def sct():NUM = 10def func_inner(n):nonlocal NUMNUM += nreturn NUMreturn func_innerst = sct()
print(st(2))
print(st(5))# global 的例子
# 用在闭包函数时,如果里面的函数,用全局变量
# 的时候,需要用global声明一下(最外层的函数,
# 不需要声明,可以直接使用全局变量)NUM = 100def sct():def func_inner(n):global NUMNUM += nreturn NUMreturn func_innerst = sct()
print(st(2))
print(st(5))
装饰器的本质:
一个闭包函数
装饰器的功能:
在不修改原函数及其调用方式的情况下对原函数功能进行扩展。
其他补充说明:
python装饰器:就是用于拓展原来函数功能的一种函数,目的是在不改变原函数名的情况下,给被装饰对象添加新的功能 。函数装饰器有开放封闭原则;开放是对扩展开放,封闭是对修改封闭。函数装饰器必须遵守的原则:一是不改变被装饰对象的源代码,二是不改变装饰对象的调用方式。
装饰器的特殊之处在于它的返回值也是一个函数,这个函数是内嵌“原“”函数的函数。
一般而言,我们要想拓展原来函数代码,需要再给原来的函数添加新的功能,最直接的办法就是进入代码里面修改,但是实际工作中,有些时候核心代码并不可以直接去改,所以在不改动原代码的情况下,我们可以再定义一个函数,但是生效需要再次执行函数,原先的调用方式可能就会改变,可能会影响你全部的代码运行,而装饰器具有的两大特点就能很好的解决这个问题:
# 装饰器例子1import time # 查看程序运行用了多少时间def timeit(func):def f_inner():start = time.time()func()end = time.time()print("time used:", end - start)return f_inner@timeit
def sum1():time.sleep(2)sum1()
# 装饰器例子2import time # 查看程序运行用了多少时间def timeit(func):def f_inner():start = time.time()func()end = time.time()print("time used:", end - start)return f_innerdef sum1():time.sleep(2)sum1 = timeit(sum1)
sum1()
# 带参数的装饰器:def wrapper(func): # 装饰器函数,func为被装饰函数def inner(*args, **kwargs):"""被装饰函数前需要添加的内容"""ret = func(*args, **kwargs) # 被装饰函数"""被装饰函数后需要添加的内容"""return retreturn inner# *args :按照位置传值,多余的参数都给args,以元祖的形式存储
# **kwargs :按照关键字传值,多余的参数个kwargs,以字典的形式存储# 使用方法@wrapper # 函数装饰器的语法糖
def fun(st):print(st)fun(91)
# 多个装饰器,从打印的结果可知,
# 在被装饰函数之前运行的是从外到内的顺序,
# 之后运行的是从内到外的顺序。def wrapper1(func):def inner(*args, **ksargs):print('wrapper1')ret = func()print('wrapper1')return retreturn innerdef wrapper2(func):def inner(*args, **ksargs):print('wrapper2')ret = func()print('wrapper2')return retreturn innerdef wrapper3(func):def inner(*args, **ksargs):print('wrapper3')ret = func()print('wrapper3')return retreturn inner@wrapper3
@wrapper2
@wrapper1
def fun():print('func1')fun()# 输出结果为:
# wrapper3
# wrapper2
# wrapper1
# func1
# wrapper1
# wrapper2
# wrapper3
"""
# 闭包函数实例
def func():name = 'python'def fc_inner():print(name)# 函数名.__closure__ 判断函数是不是闭包函数?# 当返回一个cell元素时,是闭包函数;不是闭包时,返回None。print('判断闭包函数=', fc_inner.__closure__)return fc_innerf = func()
f()
# 输出结果:python
""""""
# 第一种调用方式(装饰器)
def func_b(gr):def cs():print("主动调用函数")gr()return csdef func_a():print("被调用函数")funcs = func_b(func_a) # 第一种调用方式(装饰器)
funcs()
""""""
# 第二种调用方式(装饰器)
def func_b(gr):def cs():print("主动调用函数")gr()return cs@func_b # 第二种调用方式(装饰器)
def func_a():print("被调用函数")func_a()
"""'''
# 带参数的(装饰器)
def func_b(gr):def cs(r):print("主动调用函数")gr(r)return cs@func_b
def func_a(s):print(f"被调用函数= {s}")func_a("传参装饰器")
'''
# --------------------------------------------------
# 其他细节解释说明:
# 不同调用方式(装饰器)
def func_b(gr):def cs():print("主动调用函数")gr()return cs # 如果要去掉最下面的, func_a(),就要在cs后面加上()@func_b # 第二种调用方式(装饰器)
def func_a():print("被调用函数")func_a() # 这里要是去掉 这个函数调用。要在上面的cs的位置加上()
1、详解Python的装饰器
https://www.cnblogs.com/cicaday/p/python-decorator.html
1、装饰器是什么?
装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。
概括的讲,装饰器的作用就是为已经存在的函数或对象添加额外的功能。
前言部分:
# 普通传参
def ts_putong(something):print(something)ts_putong('cadfdy')# 元组传参
def ts_args(*args):print(args)ts_args(1, 3, 5, 'a', 'y')# lists = [1, 3, 5, 'a', 'y']
# ts_args(*lists) # 字典传参
def ts_str(**strt):print(strt)ts_str(str=1, b=3, c=9, d=2, g=7)
# dicts = {"a": 5, "b": 9}
# ts_str(**dicts)
1.1、装饰器的初步介绍:
无敌参数的介绍:
# start------------------测试无敌参数
def cesi(*args, **kwargs):print(f'第一个参数的值:{args}')print(f'第二个参数的值:{kwargs}')cesi(1, 2, 3, 4, g=2, y=9, u=50)
# end ------------------测试无敌参数
# 输出结果:
# 第一个参数的值:(1, 2, 3, 4)
# 第二个参数的值:{'g': 2, 'y': 9, 'u': 50}lists = [1, 2, 3, 4]
dicts = {'g': 2, 'y': 9, 'u': 50}
cesi(*lists, **dicts)
# 输出结果:
# 第一个参数的值:(1, 2, 3, 4)
# 第二个参数的值:{'g': 2, 'y': 9, 'u': 50}
1.2、简单的装饰器例子:
# start--------------------------------不带参数的——装饰器
def xiugai_fangf(fc):def waps():print('被调用函数的方法名字:{}()'.format(fc.__name__))return fc()# 不带参数返,返回函数需要带小括号()return waps()@xiugai_fangf
def beixiugai_fauc():print('基础方法')# end --------------------------------不带参数的——装饰器# start--------------------------- 带指定参数的的装饰器def xiugai_func(fc):def bzfunc(something):print('基础方法名字:{}()'.format(fc.__name__))return fc(something)# 带参数返回,返回函数不需要带小括号()return bzfunc@xiugai_func
def beixiugai_fauc(something):print('带指定参数的装饰器=', something)beixiugai_fauc('致虚极守静笃')# end --------------------------- 带指定参数的的装饰器# start --------------- 带无敌参数的装饰器def xiugai_func(fc):def baozhuangfunc(*args, **kwargs):print('得到被修改的方法名字{}()'.format(fc.__name__))return fc(*args, **kwargs)return baozhuangfunc@xiugai_func
def beixiugai_func(*args, **kwargs):print(f'第一个参数的值:{args}')print(f'第二个参数的值:{kwargs}')# beixiugai_func(4, 6, 8, 9, u=5, y=7, n=3)lists = [4, 6, 8, 9]
dicts = {'u': 5, 'y': 7, 'n': 3}
beixiugai_func(*lists, **dicts)# end --------------- 带无敌参数的装饰器
# 测试代码块用了多少时间。
import timedef f_a_b(sr):def f_in():sr()return f_in@f_a_b
def f_time():time.sleep(3)return 6# 查看程序用例多少时间,(用的场景有:比如测试模块用例多少时间,)
start_time = time.time()
f_time()
end_time = time.time()
print(f"一共用了多少秒:{end_time - start_time}")
# 测试代码块一共用了多少时间?注意和上面方法的对比。
import timedef f_a_b(sr):def f_in():start_time = time.time()sr()end_time = time.time()print(f"一共用了多少秒:{end_time - start_time}")return f_in@f_a_b
def f_time():time.sleep(3)f_time()
# 测试代码块用了多少时间
import timedef f_a_b(sr):def f_in():start_time = time.time()sr()end_time = time.time()print(f"一共用了多少秒:{end_time - start_time}")return f_indef f_time():time.sleep(3)faf = f_a_b(f_time)
faf()
# 测试多个代码块用了多少时间
import timedef f_a_b(sr):def f_in():start_time = time.time()sr()end_time = time.time()print(f"一共用了多少秒:{end_time - start_time}")return f_in@f_a_b # f_time = f_a_b(f_time)
def f_time():time.sleep(3)@f_a_b # f_time_two = f_a_b(f_time_two)
def f_time_two():time.sleep(2)f_time()
f_time_two()
# 带参数的被装饰的函数
import timedef f_a_b(sr):def f_in(srt):start_time = time.time()sr(srt)end_time = time.time()print(f"输入的参数值:{srt};一共用了多少秒:{end_time - start_time}")return f_in@f_a_b # f_time = f_a_b(f_time)
def f_time(sr):time.sleep(sr)@f_a_b # f_time_two = f_a_b(f_time_two)
def f_time_two(sr):time.sleep(sr)f_time(1)
f_time_two(2)
# 注意观察与上面例子代码有什么逻辑不同。# 带参数的装饰器(装饰函数)
import timedef time_logger(flag=0):def f_a_b(sr):def f_in(srt):start_time = time.time()sr(srt)end_time = time.time()print(f"输入的参数值:{srt};一共用了多少秒:{end_time - start_time}")if flag:print("将此操作保留至日志")return f_inreturn f_a_b@time_logger(2) # f_time = f_a_b(f_time)
def f_time(sr):time.sleep(sr)f_time(2)
# 类装饰器:一般依靠类内部的__call__方法
# (这种调用,通过spend_bar函数传参数,实现动态函数输出)
import timeclass FunClass:def __init__(self, func):self.func = funcdef __call__(self, *args, **kwargs):# 通过传参控制,代码块的时间(args是元组,需要取第一个值)sacs = args[0]start_time = time.time()self.func(sacs)end_time = time.time()print(f'代码块一共用了多少时间:{end_time - start_time}')@FunClass
def spend_bar(rs):time.sleep(rs)# 传参控制代码逻辑
spend_bar(2)
下面的内容主要讲解,python内置装饰器:
Python中内置装饰器的使用
https://www.cnblogs.com/XhyTechnologyShare/p/11997361.html
本章节主要讲解python中内置装饰器的使用,上面有详细讲解自定义装饰器;
1.首先来说明什么是装饰器?
答:python装饰器本质上就是一个函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外的功能,
装饰器的返回值也是一个函数对象
2.python内置装饰器都有哪些?
答:特性装饰器:@property 类方法装饰器: @classmethod 静态方法装饰器:@staticmethod
3.系统装饰器详解:
3.1 @property 可以把一个实例方法变成其同名属性,以支持实例访问,它返回的是一个property属性;
import math# @property 是特性装饰器,他的作用就是在函数(方法上面)加上@property
# 通过对象调用函数的时候,不用加(),就可以直接当,属性一样调用。
class ShuXu:def __init__(self, BanJing):self.BanJing = BanJing@propertydef mian_ji(self):return self.BanJing ** 2 * math.pi@propertydef zhou_chang(self):return self.BanJing * 2 * math.pisx = ShuXu(10)
# 调属性
print(sx.BanJing)
# 调函数
print(sx.mian_ji)
print(sx.zhou_chang)
一个property对象还具有setter、deleter 可用作装饰器;
setter是设置属性值。deleter用于删除属性值。
而官方文档中给出了getter用于获取属性信息,
但是实际使用中可以直接通过property获取属性信息;class ShuXu:def __init__(self):self.BanJing = 88self.nh = 66@propertydef mian_ji(self):return self.BanJing@mian_ji.setter # 一定要用方法名.setterdef mian_ji(self, value): # 一定要传入一个新的参数,self.BanJing = value@mian_ji.deleter # 一定要用方法名.deleterdef mian_ji(self):del self.BanJingsx = ShuXu()
print('查询属性=', sx.mian_ji)# 设置属性的值(改或增)
sx.mian_ji = 100
print('输出修改后属性的值=', sx.mian_ji)# 执行最后的删除属性方法
del sx.mian_ji# 查看对象里面还有那些属性
print('输出对象里面的属性=', sx.__dict__)# 总结:使用property:在设置属性时,
# 可以对值对进检查,设置发生时,可以 修改设置的值,
# 获取属性时,可以动态地计算值。
3.2
类方法装饰器:@classmethod 修饰的方法不需要实例化,
不需要 self 参数,但第一个参数需要是表示自身类的 cls 参数,
可以来调用类的属性,类的方法,实例化对象等。
class A:NUM = 100# cls 接收的是当前类,# 类在使用时会将自身传入到类方法的第一个参数@classmethoddef get_a(cls):# 如果子类调用,则传入的是子类print('这是类本身:', cls)print('这是类属性:', cls.NUM)class B(A):NUM = 200# 调用类方法,不需要实例化就
# 可以执行类,函数(方法)(类名.函数名字())
A.get_a()
B.get_a()
3.3
静态方法装饰器:@staticmethod:改变一个方法为静态方法,
静态方法不需要传递隐性的第一参数,
静态方法的本质类型就是一个函数 一个静态方法可以直接通过类进行调用,
也可以通过实例进行调用;
import timeclass Date:def __init__(self, year, month, day):self.year = yearself.month = monthself.day = day@staticmethoddef now(): # 用Date.now()的形式去产生实例,该实例用的是当前时间t = time.localtime() # 获取结构化的时间格式return Date(t.tm_year, t.tm_mon, t.tm_mday) # 新建实例并且返回@staticmethoddef tomorrow(): # 用Date.tomorrow()的形式去产生实例,该实例用的是明天的时间t = time.localtime(time.time() + 86400)return Date(t.tm_year, t.tm_mon, t.tm_mday)a = Date(1987, 11, 27) # 自己定义时间
print(a.year, a.month, a.day)
b = Date.now() # 采用当前时间
print(b.year, b.month, b.day)
c = Date.tomorrow() # 采用明天的时间
print(c.year, c.month, c.day)
装饰器python与python装饰器相关推荐
- Python 闭包、单个装饰器、多个装饰器、装饰器修饰类、应用场景
1. 闭包 在 Python 中,函数也可以作为参数.我们可以执行下面的代码: def func(a, b):return a + bprint(func) 我们直接输出函数名,而没有加括号.输出结果 ...
- python中的装饰器介绍
http://blog.itpub.net/31473948/viewspace-2157622/ 在了解装饰器之前,我们需要知道什么闭包是什么鬼! 闭包:在一个函数内定义了一个函数f,并且这个函数f ...
- python之路---装饰器函数
阅读目录 楔子 装饰器的形成过程 开放封闭原则 谈装饰器主要功能和装饰器固定结构 带参数的装饰器 多个装饰器装饰一个函数 返回顶部 楔子 作为一个会写函数的python开发,我们从今天开始要去公司上班 ...
- python生成器和装饰器_python三大法器:生成器、装饰器、迭代器
迭代器 迭代的概念 使用for循环遍历取值的过程叫做迭代,比如:使用for循环遍历列表获取值的过程 使用for循环遍历取值的对象叫做可迭代对象, 比如:列表.元组.字典.集合.range.字符串 判断 ...
- python装饰器与闭包_Python 装饰器和闭包
Python 装饰器和闭包 装饰器是 Python 中常见的语法糖,这篇文章讲了闭包和装饰器的原理,并且分析了函数中变量的作用域,以及尝试总结了常见的坑. 装饰器基础 首先来看看装饰器的定义:装饰器本 ...
- python两个装饰器执行顺序_python中多个装饰器的执行顺序
今天讲一下python中装饰器的执行顺序,以两个装饰器为例. 装饰器代码如下: def wrapper_out1(func): print('--out11--') def inner1(*args, ...
- python中装饰器的作用_Python装饰器详解,详细介绍它的应用场景
装饰器的应用场景附加功能 数据的清理或添加:函数参数类型验证 @require_ints 类似请求前拦截数据格式转换 将函数返回字典改为 JSON/YAML 类似响应后篡改为函数提供额外的数据 moc ...
- python装饰器函数-python之路——装饰器函数
阅读目录 楔子 作为一个会写函数的python开发,我们从今天开始要去公司上班了.写了一个函数,就交给其他开发用了. deffunc1():print('in func1') 季度末,公司的领导要给大 ...
- python装饰器-Python基础-20装饰器
20.装饰器 20.1 函数基础知识 在Python中函数为一等公民,我们可以: 把函数赋值给变量 在函数中定义函数 在函数中返回函数 把函数传递给函数 20.1.1 把函数赋值给变量 在Python ...
- python中的装饰器有哪些-python 装饰器以及开发中常用的例子
有时候我们想为多个函数,同意添加某一种功能,比如及时统计,记录日志,缓存运算结果等等,而又不想改变函数代码 那就定义装饰器函数,用它来生成一个在原函数基础添加了新功能的函数,代替原函数 参考金角大王的 ...
最新文章
- javascript推荐书籍
- 15.1 集合的迭代器
- Java IdentityHashMap equals()方法与示例
- mysql多种join_MySQL的几种Join
- python当前时间怎么弄_python获取当前时间
- 下载java的jdk
- ES6_字符串模板以及其使用
- 负载均衡原理剖析与实践:负载均衡第一篇-介绍篇
- python + opencv: kalman 跟踪
- 蓝魔i11pro运行linux,不仅仅是变大了 蓝魔i11pro新玩法
- camera驱动电源配置_电源行业发展前景如何?
- Atitit uke协会产业分类法 艾提拉产业分类法五大类法 目录 1. 配第-克拉克定理概述 产业趋势 有形财物的生产转向无形的服务性生产	1 1.1. 农工商趋势法	1 1.2. 1940年,英
- 计算机更新和网络有关系吗,路由器跟网速有关系吗 电脑的网速慢怎么调
- 跨境电商热之下推ShopExpress,微盟靠什么出海寻新增量?
- joc杂志影响因子2019_化学sci期刊影响因子排名_国际化学期刊2018最新影响因子_分析测试学报影响因子...
- Windows安装猕猴桃CDN
- mysql 定义取值范围_MySQL中各种字段的取值范围
- 英特尔对手机的几个痛苦领悟
- Zeepelin系列(一)Zeepelin安装和配置以及对Hive的基本使用
- 仙女姐姐@chuu chloe和@什么七七——python图片爬虫
热门文章
- 英文和数字组合 正则 密码验证
- 升级iOS13后悔怎么办?手把手教你iOS系统降级,只要简单几步就可以!
- python中pos是什么_如何在NLTK中使用pos_标记?
- 英飞凌 DAVE™ 4.1.2 SDK 开发app学习笔记——什么是DAVE APP?
- flex布局: 每行显示n个div块,第n+1个自动换行显示
- 计算机专业简历文案,文案创意求职简历范文
- Centos测试作死命令rm -rf /
- 14款超时尚的HTML5时钟动画
- Android 活用RecyclerView分割线
- 盛迈坤电商:店铺自然流量怎么提升