对于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()

最新文章

  1. hibernate学习笔记之二 基本环境搭建
  2. 云端卫士实战录 | Java高级特性之多线程
  3. angularjs的四大特征
  4. java学习笔记--this 关键字的理解
  5. C#导出数据至excel模板
  6. 为枚举类型添加说明 zt
  7. 第一次见4.3K电阻
  8. log4j的使用方法
  9. Linux Foundation Secure Boot System Released
  10. TreeView无刷新获取text及value
  11. Linux脚本练习
  12. box-sizing
  13. 阿里巴巴Java开发手册评述
  14. 重新认识JavaScript里的数据类型
  15. yii2 使用指定数据库执行createCommand
  16. tomcat web漏洞整改--Apache Tomcat examples directory vulnerabilities
  17. js小方法积累,将一个数组按照n个一份,分成若干数组
  18. 查看Linux内置命令和外部命令
  19. sql 删除默认索引,对象 依赖于 列,由于一个或多个对象访问此列
  20. Codeforces Round #540 (Div. 3)--1118D1 - Coffee and Coursework (Easy version)

热门文章

  1. SpringCloud学习--Eureka 服务注册与发现
  2. zepto源码分析·ajax模块
  3. 数据库优化 - SQL优化
  4. OptimalSolution(1)--递归和动态规划(4)其他问题
  5. Linux安装h2数据库
  6. SOLID原则、设计模式适用于Python语言吗
  7. 持续集成学习6 jenkins自动化代码构建
  8. [BZOJ4553][HEOI2016/TJOI2016]序列
  9. [考试反思]0901NOIP模拟测试34:游离
  10. 1. 彤哥说netty系列之开篇(有个问卷调查)