晚上失眠,怒上知乎答题!

刚好最近我的python专栏里写过一篇装饰器相关的,不说废话,直接上干货! />

目录如下:1、装饰器是什么?

2、如何使用装饰器?

3、内置装饰器

一、装饰器是什么?

装饰器,顾名思义,就是增强函数或类的功能的一个函数。

这么说可能有点绕。

举个例子:如何计算函数的执行时间?

如下,你需要计算 add 函数的执行时间。​​​​​​​

# 函数

def add(a, b):

res = a + b

return res

你可能会这么写​​​​​​​

import time

def add(a, b)

start_time = time.time()

res = a + b

exec_time = time.time() - start_time

print("add函数,花费的时间是:{}".format(exec_time))

return res

这个时候,老板又让你计算减法函数(sub)的时间。不用装饰器的话,你又得重复写一段减法的代码。

def sub(a, b)

start_time = time.time()

res = a - b

exec_time = time.time() - start_time

print("sub函数,花费的时间是:{}".format(exec_time))

return res

这样显得很麻烦,也不灵活,万一计算时间的代码有改动,你得每个函数都要改动。

所以,我们需要引入装饰器。

使用装饰器之后的代码是这样的

import time

# 定义装饰器

def time_calc(func):

def wrapper(*args, **kargs):

start_time = time.time()

f = func(*args,**kargs)

exec_time = time.time() - start_time

return f

return wrapper

# 使用装饰器

@time_calc

def add(a, b):

return a + b

@time_calc

def sub(a, b):

return a - b

是不是看起来清爽多了?

装饰器的作用:增强函数的功能,确切的说,可以装饰函数,也可以装饰类。

装饰器的原理:函数是python的一等公民,函数也是对象。

定义装饰器

def decorator(func):

def wrapper(*args,**kargs):

# 可以自定义传入的参数

print(func.__name__)

# 返回传入的方法名参数的调用

return func(*args,**kargs)

# 返回内层函数函数名

return wrapper

二、使用装饰器

假设decorator是定义好的装饰器。

方法一:不用语法糖@符号​​​​​​​

# 装饰器不传入参数时

f = decorator(函数名)

# 装饰器传入参数时

f = (decorator(参数))(函数名)

方法二:采用语法糖@符号​​​​​​​

# 已定义的装饰器

@decorator

def f():

pass

# 执行被装饰过的函数

f()

装饰器可以传参,也可以不用传参。

自身不传入参数的装饰器(采用两层函数定义装饰器)

def login(func):

def wrapper(*args,**kargs):

print('函数名:%s'% func.__name__)

return func(*args,**kargs)

return wrapper

@login

def f():

print('inside decorator!')

f()

# 输出:

# >> 函数名:f

# >> 函数本身:inside decorator!

自身传入参数的装饰器(采用三层函数定义装饰器)

def login(text):

def decorator(func):

def wrapper(*args,**kargs):

print('%s----%s'%(text, func.__name__))

return func(*args,**kargs)

return wrapper

return decorator

# 等价于 ==> (login(text))(f) ==> 返回 wrapper

@login('this is a parameter of decorator')

def f():

print('2019-06-13')

# 等价于 ==> (login(text))(f)() ==> 调用 wrapper() 并返回 f()

f()

# 输出:

# => this is a parameter of decorator----f

# => 2019-06-13

三、内置装饰器

常见的内置装饰器有三种,@property、@staticmethod、@classmethod

@property

把类内方法当成属性来使用,必须要有返回值,相当于getter;

假如没有定义 @func.setter 修饰方法的话,就是只读属性

class Car:

def __init__(self, name, price):

self._name = name

self._price = price

@property

def car_name(self):

return self._name

# car_name可以读写的属性

@car_name.setter

def car_name(self, value):

self._name = value

# car_price是只读属性

@property

def car_price(self):

return str(self._price) + '万'

benz = Car('benz', 30)

print(benz.car_name) # benz

benz.car_name = "baojun"

print(benz.car_name) # baojun

print(benz.car_price) # 30万

@staticmethod

静态方法,不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。

@classmethod

类方法,不需要self参数,但第一个参数需要是表示自身类的cls参数。

例子

class Demo(object):

text = "三种方法的比较"

def instance_method(self):

print("调用实例方法")

@classmethod

def class_method(cls):

print("调用类方法")

print("在类方法中 访问类属性 text: {}".format(cls.text))

print("在类方法中 调用实例方法 instance_method: {}".format(cls().instance_method()))

@staticmethod

def static_method():

print("调用静态方法")

print("在静态方法中 访问类属性 text: {}".format(Demo.text))

print("在静态方法中 调用实例方法 instance_method: {}".format(Demo().instance_method()))

if __name__ == "__main__":

# 实例化对象

d = Demo()

# 对象可以访问 实例方法、类方法、静态方法

# 通过对象访问text属性

print(d.text)

# 通过对象调用实例方法

d.instance_method()

# 通过对象调用类方法

d.class_method()

# 通过对象调用静态方法

d.static_method()

# 类可以访问类方法、静态方法

# 通过类访问text属性

print(Demo.text)

# 通过类调用类方法

Demo.class_method()

# 通过类调用静态方法

Demo.static_method()

@staticmethod 和 @classmethod 的 区别 和 使用场景:

在上述例子中,我们可以看出,

区别

在定义静态类方法和类方法时,@staticmethod 装饰的静态方法里面,想要访问类属性或调用实例方法,必须需要把类名写上;

而@classmethod装饰的类方法里面,会传一个cls参数,代表本类,这样就能够避免手写类名的硬编码。

在调用静态方法和类方法时,实际上写法都差不多,一般都是通过 类名.静态方法() 或 类名.类方法()。

也可以用实例化对象去调用静态方法和类方法,但为了和实例方法区分,最好还是用类去调用静态方法和类方法。

使用场景

所以,在定义类的时候,

假如不需要用到与类相关的属性或方法时,就用静态方法@staticmethod;

假如需要用到与类相关的属性或方法,然后又想表明这个方法是整个类通用的,而不是对象特异的,就可以使用类方法@classmethod。

希望看到这个回答的朋友,永远不要失眠~ />

另外还有一些之前在github上总结的:测试开发面试资源、复习资料汇总

最后,欢迎加入【程序员知乎交流圈】↓↓↓程序员交流圈 - 知乎​www.zhihu.com

置顶帖我放了头条内推链接,欢迎投递~(北京上海深圳广州杭州成都武汉都在招) />

python装饰器作用-如何理解Python装饰器?相关推荐

  1. python装饰器作用和功能_python装饰器大详解

    一.作用域 在python中,作用域分为两种:全局作用域和局部作用域. 全局作用域是定义在文件级别的变量,函数名.而局部作用域,则是定义函数内部. 关于作用域,我们要理解两点: a.在全局不能访问到局 ...

  2. python装饰器原理-深入理解 Python 装饰器

    作者简介 曾凡伟,携程信息安全部高级安全工程师,2015年加入携程,主要负责安全自动化产品的设计和研发,包括各类扫描器.漏洞管理平台.安全 SaaS 平台等. Python 是一门追求优雅编程的语言, ...

  3. python装饰器的通俗理解_python装饰器的通俗理解

    在学习Python的过程中,我相信有很多人和我一样,对Python的装饰器一直觉得很困惑,我也是困惑了好久,并通过思考和查阅才能略有领悟,我希望以下的内容会对你有帮助,我也努力通过通俗的方式使得对Py ...

  4. 什么是python装饰器_深入理解 Python 装饰器

    作者简介 曾凡伟,携程信息安全部高级安全工程师,2015年加入携程,主要负责安全自动化产品的设计和研发,包括各类扫描器.漏洞管理平台.安全 SaaS 平台等. Python 是一门追求优雅编程的语言, ...

  5. python装饰器原理-深刻理解python装饰器

    我们要完全理解python装饰器,不是很容易,主要归结有如下困难: 1. 关于函数"变量"(或"变量"函数)的理解 2. 关于高阶函数的理解 3. 关于嵌套函数 ...

  6. python装饰器作用和功能_Python装饰器原理与用法分析

    这篇文章主要介绍了Python装饰器原理与用法,结合实例形式分析了Python装饰器的概念.原理.使用方法及相关操作注意事项,需要的朋友可以参考下 本文实例讲述了Python装饰器原理与用法.分享给大 ...

  7. python装饰器作用噜咕_python 装饰器的实际作用有哪些

    终于知道python的装饰器是怎么回事,那在工作中,到底能干吗用呢? 尤其对我这个只会写写脚本又不做python开发的小测试/手动无辜脸. 先说结论,肯定是有用处滴. 一.自动化测试中使用 就拿写的自 ...

  8. python装饰器作用噜咕_Python装饰器是什么?有什么价值?

    装饰器就是把一个猴子,塞入炼丹炉,然后就出来一个还是会吃桃子,但有火眼金睛的猴子:还是原来的猴子,但多了特效技能. 下面我们以下4个方面介绍Python的装饰器:什么是装饰器? 为什么Python要引 ...

  9. python with关键字_完全理解Python关键字with与上下文管理器

    如果你有阅读源码的习惯,可能会看到一些优秀的代码经常出现带有 "with" 关键字的语句,它通常用在什么场景呢?今天就来说说 with 和 上下文管理器. 对于系统资源如文件.数据 ...

最新文章

  1. linux高可用集群(HA)原理详解
  2. Laravel5.5重写实现未通过认证(多用户)跳转相应登陆页面
  3. date新的使用方法
  4. 走进 San CLI(下):实现原理
  5. boost使用Proto转换来实现的例子
  6. Python 官网宣布,正式发布 Python 3.8.0!
  7. 【STM32】SPI简介
  8. Django(part39)--制作图书管理系统
  9. linux加密框架 crypto 算法管理 - 应用角度讲解加密框架的运行流程
  10. Python MySQLdb 学习总结
  11. windows聚焦图片为什么不更新了_网站内容更新,相同内容,不同网站为什么排名不一样?...
  12. Eclipse调试时Application XXX is waiting for the debugger to attach的提示
  13. 江苏计算机二级msoffice高级应用,计算机二级考试MSOffice高级应用
  14. Windows下 使用Python 3 调用讯飞 TTS 引擎实现文本转语音
  15. 长城汽车携旗下哈弗、欧拉、长城皮卡及WEY登陆北京车展
  16. Springboot毕设项目基于Java对运动心跳数据分析系统设计与实现455j4(java+VUE+Mybatis+Maven+Mysql)
  17. 2022081班李亚楠20220901
  18. iPhone开发秘籍(一)--第一章 iPhone SDK简介
  19. [CVPR2021]pixelNeRF: Neural Radiance Fields from One or Few Images
  20. 转载分享)移动金融安全风险分析与防护

热门文章

  1. vee-validate校验demo
  2. Java小案例——使用双重for循环实现杨辉三角的输出
  3. phpstorm 使用技巧
  4. myeclipse定位代码文件位置
  5. B-JUI(Best jQuery UI) 前端框架
  6. kubeadm 线上集群部署(四) k8s node 节点初始化安装
  7. Codeforces Round #521 (Div. 3)
  8. 简单工厂模式(详细)(举例饮料)
  9. Android 开发学习随笔
  10. 20145217信息安全系统设计基础第11周学习总结