对于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装饰器的使用的更多相关文章

  1. 关于python装饰器

    关于python装饰器,不是系统的介绍,只是说一下某些问题 1 首先了解变量作用于非常重要 2 其次要了解闭包 def logger(func): def inner(*args, **kwargs) ...

  2. python装饰器通俗易懂的解释!

    1.python装饰器 刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了.总结了一下解释得比较好的,通俗易懂的来说 ...

  3. Python 装饰器学习

    Python装饰器学习(九步入门)   这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 1 2 3 4 5 6 7 8 # -*- c ...

  4. python 装饰器修改调整函数参数

    简单记录一下利用python装饰器来调整函数的方法.现在有个需求:参数line范围为1-16,要求把9-16的范围转化为1-8,即9对应1,10对应2,...,16对应8. 下面是例子: def fo ...

  5. python 装饰器学习(decorator)

    最近看到有个装饰器的例子,没看懂, #!/usr/bin/python class decorator(object): def __init__(self,f): print "initi ...

  6. Python装饰器详解

    python中的装饰器是一个用得非常多的东西,我们可以把一些特定的方法.通用的方法写成一个个装饰器,这就为调用这些方法提供一个非常大的便利,如此提高我们代码的可读性以及简洁性,以及可扩展性. 在学习p ...

  7. 关于python装饰器(Decorators)最底层理解的一句话

    一个decorator只是一个带有一个函数作为参数并返回一个替换函数的闭包. http://www.xxx.com/html/2016/pythonhexinbiancheng_0718/1044.h ...

  8. Python装饰器由浅入深

    装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们 ...

  9. Python装饰器与面向切面编程

    今天来讨论一下装饰器.装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数 ...

  10. python装饰器方法

    前几天向几位新同事介绍项目,被问起了@login_required的实现,我说这是django框架提供的装饰器方法,验证用户是否登录,只要这样用就行了,因为自己不熟,并没有做过多解释. 今天查看dja ...

随机推荐

  1. Docker学习3-简单shell脚本安装mysql5.7与docker小技巧

    前言 玩过Windows中的 .bat 的小伙伴是不是觉得很有意思呢,github中一键推送.同步拉取等等操作,哈哈,当然shell脚本也是很类似,可以运行一个脚本就可以自动给我们部署好环境啦!但是这 ...

  2. 关于while和do while 的个人理解

    先上代码 int x=425; System.out.println("循环开始,我的初始值为:x="+x); //425 do { System.out.println(&quo ...

  3. 实战SpringCloud响应式微服务系列教程(第八章)构建响应式RESTful服务

    本文为实战SpringCloud响应式微服务系列教程第八章,讲解构建响应式RESTful服务.建议没有之前基础的童鞋,先看之前的章节,章节目录放在文末. 1.使用springboot2.1.4构建RE ...

  4. Activity 学习(二) 搭建第一个Activity流程框架

    本次示例使用的IDER测试完成 测试背景 : xx饿了去饭店吃饭  需要先和服务员点餐  点完餐后服务员将菜品传递给厨师制作  制作完成后吃饱 一 :创建流程图 创建上一篇测试成功出现的BpmnFil ...

  5. CCBPM工作流系统中如何在特定的一个步骤,调用起另外一条流程

    关键词: 工作流快速开发平台  工作流设计  业务流程管理   asp.net 开源工作流bpm工作流系统  java工作流主流框架  自定义工作流引擎 需求描述: 1, 操作员在操作最后一个节点时, ...

  6. rsync的笔记整理

    Rsyncd数据同步工具 1.什么是Rsyncs? Rsync(Remote synchronization)是一款开源的,快速的,多功能的,可实现全量及增量的本地或远程数据同步备份的优秀工具.Rsy ...

  7. 回话技术-Cookie-记录上一次访问时间

    效果: 第一次访问: 再次访问: <%@ page import="java.util.Date" %> <%@ page import="java.t ...

  8. 一个开源组件 bug 引发的分析

    这是一个悲伤的故事.某日清晨,距离版本转测还剩一天,切图仔的我正按照计划有条不紊的画页面.当我点击一个下拉弹框组件中分页组件页数过多而出现的向后 5 页省略号时,悲剧开始了,弹框被收回了.情景再现 问 ...

  9. CSPS模拟 80

    题还没改完就来臭不要脸的写反思了. (主要因为太困了懒得改了) (还因为T2看起来太过弱智) (也许等我生物钟恢复正常后能当做课余消遣水一水) statistic:skyh接了两杯水,真能喝啊 然后他 ...

  10. 【ASP.NET Core学习】Entity Framework Core

    这里介绍在ASP.NET Core中使用EF Core,这里数据库选的是Sql Server 如何使用Sql Server 添加模型 && 数据库迁移 查询数据 保存数据 如何使用Sq ...