面试 JavaWeb 单例模式 shell mongoose Validator 百度seo关键词 vue的钩子函数 vue双向绑定 后台系统模板 网赚视频教程 photoshop cs3 教程 android小程序源代码 matlab定义空矩阵 js获取body的高度 bootstrap颜色 python中import python用什么数据库 java字符串长度 java继承关键字 java中的string java抛出自定义异常 java配置jdk 如何强行退出小米账号 ps怎么插入表格 java游戏编程 在线手册 源计划艾克 vue路由跳转 ps3d字体 js取余数 目标聚光灯 qq流览器下载 预测未来长相的软件 qq浏览器全屏 脚本怎么用 vue搭建项目 c4d克隆 id书籍排版教程 mac字体库
当前位置: 首页 > 学习教程  > 编程语言

Python装饰器

2020/7/24 10:30:36 文章标签:

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

举例:现计算 add 函数的执行时间

import time
def add(a,b):
    start_time=time.time()
    res=a+b
    exec_time=time.time()-start_time
    return res

然后又计算sub函数的执行时间,如果不使用装饰器

​
import time
def add(a,b):
    start_time=time.time()
    res=a-b
    exec_time=time.time()-start_time
    return res

如果使用装饰器,就可以减少sub函数前后的重复代码

import tima

# 定义装饰器
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
    return wrapper # 返回收到的结果到“原函数”

# 函数传入time_calc的参数后,先不执行wrapper函数,而是先return wrapper,
# 即开始执行wrapper函数,同时“原函数”的参数a、b传入*args,**kargs

# 使用装饰器
@time_calc
def add(a,b):
    return a+b

@time_calc:
    return a-b

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

3、原理:函数是python的一等公民,函数也是对象。

4、使用装饰器

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

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!

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

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('this is a parameter of decorator')
def f():
    print('2020-07-24')

f()

# 输出
# this is a parameter of decorator---f
# 2020-07-24

5、内置装饰器

常见的内置装饰器:

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

2)@staticmethod:静态方法。与普通方法类似,参数里面不用self,若此方法和类相关,但又不需要类和实例中的任何信息、属性等,就可以选择静态方法。比如我们检查是否开启了日志功能,这个和类相关,但是跟类的属性和实例都没有关系。

# -*- coding:utf-8 -*-
log_enabled = True

class A:
    class_attr = "attr"
    
    def __init__(self):
        pass
        
    @staticmethod
    def static_foo():
        if log_enabled:
            print("log is enabled")
        else:
            print("log is disabled")
        

A.static_foo()

3)@classmethod:类方法。当我们只需和类直接进行交互,而不需要和实例进行交互时,类方法是最好的选择。类方法与实例方法类似,但是传递的不是类的实例,而是类本身,第一个参数是cls我们可以用类的实例调用类方法,也可以直接用类名来调用。

# -*- coding:utf-8 -*-
class A:
    class_attr = "attr"
    
    def __init__(self):
        pass
        
    @classmethod
    def class_foo(cls):
        print("running class_foo(%s)" % (cls.class_attr))

a = A()
a.class_foo()
A.class_foo()

 


本文链接: http://www.dtmao.cc/news_show_50308.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?