zoukankan      html  css  js  c++  java
  • python笔记-装饰器

    一、装饰器

    python的装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。简单的说装饰器就是一个用来返回函数的函数

    1. 它能使函数的功能得到扩充,而同时不用修改函数本身的代码。
    2. 它能够增加函数执行前、执行后的行为,而不需对调用函数的代码做任何改变。

    执行流程:在执行装饰器修饰的函数时,python解释器会将被装饰的函数当成参数传入装饰器函数中。将装饰器函数的返回值当成函数调用,被装饰函数的参数继续传递给装饰器函数的返回值。

    二、函数装饰器

    2.1 简单装饰器

    以下代码, 是一个简单的装饰器

    def func(f):
        print("%s执行结果" % f.__name__, end=": ")
        f()
    
    
    def test():
        print("hello world")
    
    
    func(test)
    
    1. func函数是装饰器函数
    2. test函数是被装饰函数
    3. 功能就是, 在不修改test函数的代码前提下, 增加一个输出函数名的功能.

    2.2 装饰器

    不带参数的装饰器

    def decorator(func):
        def run(*args, **kwargs):
            print("函数%s执行结果: %d" % (func.__name__, func(args[0], args[1])))
        return run
    
    
    @decorator
    def mul(a, b):
        return a * b
    
    
    mul(3, 4)  # 输出 函数mul执行结果: 12
    
    1. @运算符: 标记装饰器
    2. 装饰器执行机制:
      1. 被装饰的函数mul在调用时, 被解释器检查到有装饰器标志.
      2. 不会立即执行mul函数, 解释器会将mul函数当参数, 传递到装饰器函数decorator内部.
      3. 由装饰器函数的内部run函数对mul函数进行装饰.
      4. 当完成修饰函数mul后, 装饰器函数会将其内部函数run返回, 并当成函数进行调用. mul函数的参数, 则会传递到装饰器函数返回的run函数.

    示例
    使用装饰器, 要求打印出是哪个函数执行的结果

    def func(f):
        def run():
            print("%s执行结果" % f.__name__, end=": ")
            f()
        return run
    
    
    @func
    def test():
        print("hello world")
    
    
    # func(test)
    test()
    

    带参数的装饰
    实现一个计算功能, 要求可以查看是谁调用的这个计算功能

    def set_name(name):
        def decorator(func):
            def run(*args, **kwargs):
                print("%s调用计算函数%s执行结果为: %.2f" %(name, func.__name__, func(args[0], args[1])))
            return run
        return decorator
    
    
    @set_name("小芳")
    def div(a, b):
        return a / b
    
    
    div(3, 2)
    
    1. set_name("小芳"): 因为对set_name进行调用, set_name函数已被执行. 返回值是decorator函数
    2. 可以将@set_name('小芳')理解为@decorator. 这样就可以将被装饰函数传入到内层函数

    三、内置装饰器

    1. property: 属性装饰
    2. staticmethod: 静态方法装饰
    3. classmethod: 类方法装饰器
    class Cls:
    
        @property  # 以属性形式调用方法
        def test01(self):
            return '以属性形式调用方法'
    
        @staticmethod  # 不会自动传入self
        def test02():
            print('不会自动传入实例')
    
        @classmethod
        def test03(cls):
            print('将类自动传入')
    

    四、类装饰

    class Decorator:
        def __init__(self, fun):
            self.fun = fun
    
        def __call__(self, *args, **kwargs):
            print("函数%s执行结果: %d" % (self.fun.__name__, self.fun(args[0], args[1])))
    
    
    @Decorator
    def minus(a, b):
        return a - b
    
    
    minus(20, 3)
    
    1. 装饰器函数的返回值, 当成了函数继续调用, 被装饰函数的参数就传递给了装饰器函数的返回值
    2. 使用类装饰器, 必须定义 __init____call__两个方法
      1. __init__方法用于接收被装饰的函数名
      2. __call__方法用于编写修饰 被装饰函数的逻辑, 也即是接受被装饰函数的参数
  • 相关阅读:
    特殊字符,如Emoji表情Base64存储到数据库
    判断文本文件的编码
    很多.net 程序员不知道又非常重要的 .net高级调试技巧.调试别人的dll方法内的变量
    没想到你是这样的Linux
    PDF转成txt
    生成云图
    Data collection (imaging)
    Python Conda 软件包升级
    电镜作业2的脚本版本
    电镜作业2
  • 原文地址:https://www.cnblogs.com/duyupeng/p/13171853.html
Copyright © 2011-2022 走看看