Python学习笔记之装饰器的使用

一、装饰器的分类:通用装饰器;类装饰器;property属性装饰器

  1. 装饰器的作用:在不改变原有函数源代码的情况下,给函数增加新的功能。(装饰器其实也是闭包的一种)
  2. 语法格式
    装饰器
    def decorator(fn):  # fn为被装饰的目标函数
        def inner():
            '''执行函数之前'''
               fn() # 执行装饰的目标函数
               '''执行函数之后'''
        return inner
  3. 使用步骤:
# 定义一个装饰器

def check(fn):
    def inner():
        print("请先登录-----")
        fn()
    return inner


# 定义一个被装饰的函数

# 方法一:
@check
def comment():
    print("发表评论")


# 使用装饰器装饰函数

# 方法二:comment = check(comment)

# 调用函数
comment()

 注意:① fn = comment => fn() = comment()

           ②check的返回值为inner ,=> comment = inner => comment() = inner。【这里的comment函数发生了改变】

3、使用@符号也能执行刚才的方法, @check 与 comment  = check(comment)的效果相同。

二、通用装饰器的使用:

  1. 装饰带有参数的函数

示例:

# 定义装饰器
def loggin(fn):    # fn = sum_num
    def inner(a,b):
        fn(a,b)
    return inner # sum_num = inner

# 使用装饰器装饰函数
@loggin
def sum_num(a,b):
    result = a + b
    print(result)


# 调用函数
sum_num(1,2)

    2.装饰带有返回值的函数:

# 定义装饰器
def loggin(fn):    # fn = sum_num
    def inner(a,b):
        result = fn(a,b)
        return result
    return inner # sum_num = inner

# 使用装饰器装饰函数
@loggin
def sum_num(a,b):
    result = a + b
    return result


# 调用函数
result = sum_num(1,2)
print(result)

   3.装饰带有不定参数的函数:

# 定义装饰器
def loggin(fn):    # fn = sum_num
    def inner(*args, **args):
        fn(*args, **args)
    return inner # sum_num = inner

# 使用装饰器装饰函数
@loggin
def sum_num(*args, **kwargs):
    print(args,kwargs)


# 调用函数
sum_num(1,2,age = "18")

  4.多个装饰器的使用:

# 定义装饰器1
def check1(fn1):
    def inner1():
        print("登录验证1")
        fn1()
    return inner1



# 定义装饰器2
def check2(fn2):
    def inner2():
        print("登录验证2")
        fn2()
    return inner2

# 被装饰的函数
@check1
@check2
# 离函数近的装饰器先装饰,然后外面的装饰器再进行装饰,由内到外的过程
def comment():
    print("发表评论")


# 调用函数
comment()

5.带参数的装饰器:

# 装饰器
def loggin(flag): # flag = "+"


    # 外部函数
    def decorator(fn):
    # 内部函数
        def inner(num1,num2):
            # 判断过程
            if flag == "+":
                print("--正在努力进行加法计算--")
            elif flag == "-":
                print("--正在努力进行减法运算--")
            result = fn(num1,num2)
            return result
        return inner

    # 返回装饰器
    return decorator


# 被带有参数装饰器装饰的函数
@decorator("+")        # 1.loggin("+") 2.@decorator起到装饰器的功能了
def add(a,b):
    result = a + b
    return result

# 执行函数
result = add(1, 3)
print(result)

:①装饰器的外部函数只接受一个参数---被装饰的函数

       ②需要给装饰器传参数需要在装饰器的外部再增加一个函数

三、类装饰器

    1.__call__方法的使用

       一个类里面一旦实现了__call__方法,那么这个类创建的对象就是一个可调用的对象,可以像函数一样进行调用。

        2.示例:

# 定义类装饰器
class Check(object):
    def __init__(self,fn):
        self.__fn = fn
    
    def __call__(self, *args, **kwargs):
        print("登录")
        self.__fn()    # comment()

# 被装饰的函数
@Check  # comment = Check(comment)
def comment():
    print("发表评论")

# 调用函数
comment()

:①想要让类的实例对象能够像函数一样进行调用,需要在类里面使用call方法,把类的实例变成可调用对象。

        ②类装饰器装饰功能在call方法里面添加。

四、property属性装饰器

        1、定义:property属性就是负责把类中的一个方法当做属性进行使用,这样可以简化代码。

        2、定义property属性有两种方式:①装饰器方式;②类属性方式。

        3、装饰器方式:

                示例:

class Person(object):
    def __init__(self):
        self.__age = 0
    
    # 装饰器方式的property,把age方法当做属性使用,表示当获取属性时会执行下面修饰的方法
    @property
    def age(self):
        return self.__age

    # 把age方法当做属性使用,表示当获取属性时会执行下面修饰的方法
    @age.setter
    def age(self,new_age):
        if new_age >= 150:
            print("成精了")
        else:
            self.__age = new_age


# 调用函数
p = Person()

# 得到函数值
p.age
print(p.age)

# 设置修改函数值
p.age = 88
print(p.age)

  注:•@property 表示把方法当做属性使用,表示获取属性时会执行下面修饰的方法。

         •@方法名.setter 表示把方法当做属性使用,表示当设置属性时会执行下面修饰的方法。

         •装饰器方式的property属性1修饰的方法名一定要一样.

4.类属性方式:

        示例

class Person(object):
    def __init__(self):
        self.__age = 0
    
    def get_age(self):
        '''当获取get属性的时候会执行该方法'''
        return self.__age
    
    def set_age(self,new_age):
        '''当设置age属性的时候会执行该方法'''
        if new_age >= 150:
            print("成精了")
        else:
            self.__age = new_age

# 类属性的方式property属性
    age = property(get_age,set_age)

p = Person)
print(p.gae)
print(p.age = 88)

上一篇:创建数据表


下一篇:微服务-下单退单流程