python 装饰器

装饰器

装饰本质上就是一个闭包函数,它可以对我们已有函数进行额外的功能拓展,装饰器符合了 开发中的封闭开放原则

装饰器的作用

在不改变原有函数的源代码的情况下,给函数增加新的功能

def decorator(fn):           # fn: 需要装饰的函数
    def inner():
        '''函数执行之前需要执行的代码'''
        fn() # 执行被装饰的目标函数
        '''函数执行之前需要执行的代码'''
    return inner

装饰器的使用

# 定义一个装饰器
def login(fn):
    def inner():
        print('登录')
        fn()
    return inner


# 定义需要被装饰的函数
def comment():
    print('评论')

comment = login(comment)
comment()

执行结果

装饰器语法糖

如果每次编写代码都要写comment = login(comment),那台麻烦了,所以就有了更简洁的写法,语法糖

格式:@装饰器名字

def login(fn):
    def inner():
        print('登录')
        fn()
    return inner

@login
def comment():
    print('评论')

comment()

执行结果

简单小案例

打印数字1-1000需要花费多少时间?

import time

def decorator(func):
    def inner():
        start_time = time.time()
        func()
        end_time = time.time()
        print(f"打印数字1-1000需要花费{end_time - start_time}")
    return inner

@decorator
def func1():
    for i in range(1000):
        print(i)

func1()

执行结果

装饰带有参数的函数

def decorator(fn):
    def inner(a, b):
        fn(a, b)
    return inner

@decorator
def sum_num(a, b):
    result = a + b
    print(result)

sum_num(1, 2)

装饰的函数带有返回值

def decorator(fn):
    def inner(a, b):
        return fn(a, b)
    return inner

@decorator
def sum_num(a, b):
    result = a + b
    return result

result = sum_num(1, 2)
print(result)

装饰的函数带有不定长参数

def decorator(fn):
    def inner(*args, **kwargs):
        fn(*args, **kwargs)
    return inner

@decorator
def sum_num(*args, **kwargs):
    print(args, kwargs)

sum_num(1, 2, 3, name='张三', age='李四')

通用装饰器

def decorator(fn):
    def inner(*args, **kwargs):
        result = fn(*args, **kwargs)
        return result
    return inner

@decorator
def sum_num(*args, **kwargs):
    return args, kwargs

print(sum_num(1, 2, 3, name='张三'))

多个装饰器的使用

多个装饰器装饰一个函数

def check1(fn):
    def inner():
        print('登录一')
        fn()
    return inner

def check2(fn):
    def inner():
        print('登录二')
        fn()
    return inner

@check1
@check2
def comment():
    print('评论')

comment()

执行结果 

带有参数的装饰器

def check(flag):             # 这里起到了函数里面的所有函数都能够用到flag
    def decorator(fn):

        def inner(num1, num2):

            if flag == '+':
                print('正在进行加法运算')
                return fn(num1, num2)

        return inner

    return decorator

@check('+')   # 第一层函数只是为了接受参数
def add(a, b):
    result = a + b
    return result

print(add(1, 5))

执行结果

类装饰器

一个类里面一旦实现了__call__方法,那么这个类实例化出来的对象就可以像函数一样进行调用

class Check():

    num = 1

    def __call__(self):
        print('call方法被调用')
        print(self.num)

result = Check()
result()

执行结果

使用类装饰器
class Check(object):
    def __init__(self, fn):
        self.__fn = fn               # fn = comment

    def __call__(self, *args, **kwargs):
        print('登录')
        self.__fn()

@Check
def comment():
    print('评论')

comment()

执行结果

property属性

property属性可以把类中的一个方法当作属性来进行使用

定义property属性有两种方式

  • 装饰器方式
  • 类属性方式

装饰器方式
@property   把方法当作属性使用,当获取属性时会执行下面修饰的方法
@方法名.setter   把方法当作属性使用,当设置属性时会执行下面修饰的方法


装饰器方法 的property属性修饰的方法名一定要一样

class Person(object):
    def __init__(self):
        self.__age = 18

    @property
    def age(self):
        return self.__age

# 获取属性
p = Person()
print(p.age)
class Person(object):
    def __init__(self):
        self.__age = 18

    @property
    def age(self):
        return self.__age

    @age.setter
    def age(self, new_age):
        self.__age = new_age

# 获取属性
p = Person()
print(p.age)

# 修改属性
p.age = 100
print(p.age)

类属性装饰器
property的参数说明:
第一个参数是获取属性时要执行的方法
第二个参数时设置属性时要执行的方法

class Person(object):
    def __init__(self):
        self.__age = 18

    def get_age(self):
        return self.__age

    def set_age(self, new_age):
        self.__age = new_age

    age = property(get_age, set_age)

# 获取属性
p = Person()
print(p.age)

# 修改属性
p.age = 100
print(p.age)

  • 21
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值