装饰器

概述

装饰器(Decorators)
装饰器是Python的一个重要部分。简单地说:他们是修改其他函数的功能的函数。他们有助于让我们的代码更简洁,也更Pythonic。

  1. property类装饰器
    1. property()
    2. @property
  2. 闭包装饰器
    1. 指定参数个数
    2. 通用

假设我们要创建一个学生类,用set和get方法来修改实例属性

class Student():
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    def get_age(self):
        return self.__age

    def set_age(self, age):
        if 0 < age < 100:
            self.__age = age
        else:
            print("年龄不合理")

student1 = Student("Rico", 21)
print(student1.get_age())
student1.set_age(18)
print(student1.get_age())

现在我们利用装饰器来简化类的方法和函数功能,在使用实例对象时让代码跟简洁。

  • @property
class Student():
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

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

    @age.setter
    def age(self, age):
        if 0 < age < 100:
            self.__age = age
        else:
            print("年龄不合理")


student1 = Student("Rico", 21)
print(student1.age)
student1.age = 18
print(student1.age)

@property 可将方法调用转换为属性调用,被装饰的方法会直接进行内部托管,这样就使得实例属性在使用过程中方便了很多。

  • property()
class Student():
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    def get_age(self):
        return self.__age

    def set_age(self, age):
        if 0 < age < 100:
            self.__age = age
        else:
            print("年龄不合理")
    age = property(get_age, set_age)


student1 = Student("Rico", 21)
print(student1.age)
student1.age = 18
print(student1.age)

这里介绍一下property()的使用,

class property(fget=None, fset=None)

如果c是Student的一个实例,c.x将调用getter ;c.x = value将调用setter。

  • 闭包装饰器

首先,来创建一个闭包

def fuc_out(func):
    def fuc_in(name, age):
        func(name, age)
    return fuc_in

def student(name, age):
    if 0 < age < 100:
        print("姓名:{};年龄:{}".format(name, age))
    else:
        print("年龄不合理")


student1 = fuc_out(student)
student1("Rico", 22)

 使用闭包装饰器

def fuc_out(func):
    def fuc_in(a, b):
        func(a, b)
        # 添加一个新功能
        method()
    return fuc_in

def method():
    print("我是一个新功能")

@fuc_out
def student(name, age):
    if 0 < age < 100:
        print("姓名:{};年龄:{}".format(name, age))
    else:
        print("年龄不合理")


student("Rico", 22)

在此例中,@fuc_out相当于代替了student1=fuc_out(student)创建的过程。

这里简述一下闭包的作用,某些情况下我们不能对原本的代码方法进行修改,这时可以利用闭包来调用函数方法并添加为其新方法。另外,亦可以使用闭包来将函数方法进行组合,实现面向对象的编程目的。

  • 通用装饰器

上述实例中,限定了student的参数,加入我现在需要给学生添加一个学号,那么就需要传递三个参数,这样就需要重新修改闭包的参数容量。

其实并不需要这样做,仅仅改动一个地方就可以了:

def fuc_out(func):
    def fuc_in(*args, **kwargs):
        func(*args, **kwargs)
        #增添功能
        method()
    return fuc_in

def method():
    print("我是一个新功能")

@fuc_out
def student(name, age):
    if 0 < age < 100:
        print("姓名:{};年龄:{}".format(name, age))
    else:
        print("年龄不合理")

@fuc_out
def student_add_id(name, age, id):
    if 0 < age < 100:
        print("姓名:{};年龄:{};学号:{}".format(name, age, id))
    else:
        print("年龄不合理")

student1 = student("Andy", 18)
student2 = student_add_id("Rico", 21, 123456789)

直接使用*args和**kwargs就解决了多个参数传递的问题。

*args 可以接受元组类型;**kwargs可以接受字典类型。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值