Python装饰器的使用
对于python编程人员,装饰器的使用肯定是必不可少的。
装饰器分为系统定义装饰器和自定义装饰器;系统定义装饰器:@classmethod:类方法装饰器 @staticmethod: 静态方法装饰器 @property修饰的方法是属性方法,属性方法被调用时不需要在方法后加括号 详细请参考python内置装饰器的使用。
装饰器的本质就是一个函数,作用是在不改变源代码的情况下,给函数增加额外的功能;装饰器的使用通过@语法糖进行调用
自定义装饰器又分为:带参的装饰器和不带参的装饰。
先来说不带参的装饰器:
# 1.声明一个普通的装饰器
# 需求:获取每个函数的运行时间
import datetime,time def get_func_time(func): # 外层作为装饰函数,必须接收参数,将被装饰函数传入
def inner(*args): # 内层实现被装饰函数的额外功能,如果被装饰函数需要传入参数,可以定义不定长参数:*args,或者关键字参数:**kwargs
start_time = datetime.datetime.now() # 获取当前时间,作为开始时间
result = func(*args) # 调用传入的被装饰的函数,传入需要的参数
end_time = datetime.datetime.now() # 获取当前时间,作为结束时间
print('程序的运行时间为:', end_time - start_time)
return result # 如果被装饰函数是有返回值的,在此也应该将结果进行返回
return inner # 必须将内层函数对象返回,如果不返回会报:typeError @get_func_time
def program(): #该函数不需要传入参数
# 被装饰函数,实现休息三秒
time.sleep(3)
# 调用函数:
program()
程序的执行结果

@get_func_time
def get_max_common_divisor(num1,num2): # 这是一个需要传入参数的函数
'''
求两数的最大公约数
'''
max_common_divisor = 0
min_num = min(num2,num1)
for i in range(1,min_num+1):
if num1 % i == 0 and num2 % i ==0:
print('这是一个公约数:',i)
max_common_divisor = i
return max_common_divisor
# 调用函数:
get_max_common_divisor(20, 10)

然后我们写一个带有参数的装饰器:
# 需求实现打印不同花边的姓名 # 如果需要声明一个带有参数的装饰器,则需要嵌套三层函数,最外层进行选择判断。
def decorator(choice):
if choice == '*':
def out(func):
def inner(*args):
print('**********')
func(*args)
print('**********')
return inner
return out
elif choice == '-':
def out(func):
def inner(*args):
print('----------')
func(*args)
print('----------')
return inner
return out
else:
def decorator(func):
def inner(*args):
print('%%%%%%%%%%')
func(*args)
print('%%%%%%%%%%')
return inner
return decorator @get_func_time # 调用装饰器使用:@装饰器名称 # 一个函数可以调用多个装饰器
@decorator(choice='-')
def get_name(name):
# 源代码:打印姓名
print(name) get_name('刘德华')

除了可以声明函数装饰器还可以声明一个类装饰器;如果要声明一个类装饰器必须实现__call__方法;__call__方法的使用参考下方
# 不带参数的类装饰器类装饰器
import time,datetime
class class_decorator(): def __init__(self,func): # __init__方法用于接收传入的函数
self.func = func def __call__(self, *args, **kwargs): # call方法则相当于函数装饰器的内层函数
start = datetime.datetime.now()
self.func()
end = datetime.datetime.now()
return end - start
@class_decorator
def programs():
print('程序开始')
time.sleep(3)
print('程序结束') program_time = programs()
print('程序运行时间为:',program_time)

# 带参数的类装饰器
class decorator(): def __init__(self,language): # init 方法接收的不在是传入的函数,接收的是参数
self.language = language def __call__(self,func): # 函数通过call方法传入
if self.language=='中文': # 执行判断
def inner(*agrs,**kwargs):# 内层函数增加功能
name = func(*agrs)
return '你好' + name
return inner
elif self.language == 'English':
def inner(*agrs, **kwargs):
name = func(*agrs)
return 'Hello\t' + name
return inner @decorator('English')
def aaa(name):
return name name = aaa('张三')
print(name)

补充:__call__方法的使用;__call__ 方法实现将类实例变成一个可以调用的函数
class B():
def __init__(self):
print('这是初始化方法') def __call__(self):
print('这是call方法') b = B()
b()

Python装饰器的使用的更多相关文章
- 关于python装饰器
关于python装饰器,不是系统的介绍,只是说一下某些问题 1 首先了解变量作用于非常重要 2 其次要了解闭包 def logger(func): def inner(*args, **kwargs) ...
- python装饰器通俗易懂的解释!
1.python装饰器 刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了.总结了一下解释得比较好的,通俗易懂的来说 ...
- Python 装饰器学习
Python装饰器学习(九步入门) 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 1 2 3 4 5 6 7 8 # -*- c ...
- python 装饰器修改调整函数参数
简单记录一下利用python装饰器来调整函数的方法.现在有个需求:参数line范围为1-16,要求把9-16的范围转化为1-8,即9对应1,10对应2,...,16对应8. 下面是例子: def fo ...
- python 装饰器学习(decorator)
最近看到有个装饰器的例子,没看懂, #!/usr/bin/python class decorator(object): def __init__(self,f): print "initi ...
- Python装饰器详解
python中的装饰器是一个用得非常多的东西,我们可以把一些特定的方法.通用的方法写成一个个装饰器,这就为调用这些方法提供一个非常大的便利,如此提高我们代码的可读性以及简洁性,以及可扩展性. 在学习p ...
- 关于python装饰器(Decorators)最底层理解的一句话
一个decorator只是一个带有一个函数作为参数并返回一个替换函数的闭包. http://www.xxx.com/html/2016/pythonhexinbiancheng_0718/1044.h ...
- Python装饰器由浅入深
装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们 ...
- Python装饰器与面向切面编程
今天来讨论一下装饰器.装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数 ...
- python装饰器方法
前几天向几位新同事介绍项目,被问起了@login_required的实现,我说这是django框架提供的装饰器方法,验证用户是否登录,只要这样用就行了,因为自己不熟,并没有做过多解释. 今天查看dja ...
随机推荐
- CodeForces - 1214D B2. Books Exchange (hard version)
题目链接:http://codeforces.com/problemset/problem/1249/B2 思路:用并查集模拟链表,把关系串联起来,如果成环,则满足题意.之后再用并查集合并一个链,一个 ...
- CheckBox状态多选
前: <StackPanel Margin="> <Label FontWeight="Bold">Application Options< ...
- Spring Boot2 系列教程(十八)Spring Boot 中自定义 SpringMVC 配置
用过 Spring Boot 的小伙伴都知道,我们只需要在项目中引入 spring-boot-starter-web 依赖,SpringMVC 的一整套东西就会自动给我们配置好,但是,真实的项目环境比 ...
- IDEA配置maven+错误记录
使用maven并不是那么顺利所以把自己遇到的问题也记录一下 下载maven 从官网下载maven官网 配置环境变量 新建一个变量名:MAVEN_HOME 值:maven目录 path:%MAVEN_H ...
- 爬虫链接mongodb 以及多线程多进程的操作
一.连接mongodb 1. 设置数据库 client=pymongo.MongoClient(‘localhost’) 2. db=client[‘lag ...
- fenby C语言 P28
#include <stdio.h> int main(){ int *p1,*p2,a=10,b=20,c; p1=&a; p2=&b; if(a<b) { c=a ...
- (IDEA) 搭建Maven并使用Maven打包部署
1.配置Maven的环境变量 a.首先我们去maven官网下载Maven程序,解压到安装目录,如图所示: b.配置M2_HOME的环境变量,然后将该变量添加到Path中 备注:必须要有JAVA_HOM ...
- NLP预训练模型-百度ERNIE2.0的效果到底有多好【附用户点评】
ERNIE是百度自研的持续学习语义理解框架,该框架支持增量引入词汇(lexical).语法 (syntactic) .语义(semantic)等3个层次的自定义预训练任务,能够全面捕捉训练语料中的词法 ...
- P4568 [JLOI2011]飞行路线 分层图
题目描述 Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在nn个城市设有业务,设这些城市分别标记为00到n-1n−1,一共有mm种航线,每种航线连接两个城市,并且 ...
- 浅谈OI中的底层优化!
众所周知,OI中其实就是算法竞赛,所以时间复杂度非常重要,一个是否优秀的算法或许就决定了人生,而在大多数情况下,我们想出的算法或许并不那么尽如人意,所以这时候就需要一中神奇的的东西,就是底层优化: 其 ...