Python11--装饰器

作者: 伊洛的小屋 | 来源:发表于2020-08-31 14:32 被阅读0次
1.装饰器定义
  • 装饰器本质上是一个函数,可以接受一个函数作为参数
2.装饰器简单的例子
  • 承接之前的内容,英雄释放火焰技能。打印出英雄释放技能的时间
#!/usr/bin/python
from datetime import datetime

def release_skills(hero):
    def release_skill(*skill, **skills):
        print(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
        return hero(*skill, **skills)
    return release_skill


@release_skills
def hero(name, skill):
    return (name + '-->'+'释放技能:'+ skill)


print(hero('关羽', 'fire'))
print(hero.__name__)
  • 如上,release_skills装饰器负责打印释放技能的时间
(yiluo) ➜  Code python hero.py
2019-12-12 11:11:49
关羽-->释放技能:fire
release_skill
  • 我们运行hero函数的时候,同时打印出了英雄释放火焰技能的时间
  • 可是我们发现了一个比较严重的问题,hero 函数应变成了release_skill函数了,看上面的代码,确实hero已经被release_skill改变了
  • 那如何解决这个被改变的问题呢? 总不能用完装饰器,被装饰的函数已经不是之前的函数吧,还好Python 提供了方法解决这个问题
# 作者:伊洛Yiluo 公众号:伊洛的小屋
# 个人主页:https://yiluotalk.com/
# 博客园:https://www.cnblogs.com/yiluotalk/
#!/usr/bin/python
from datetime import datetime
from functools import wraps

def release_skills(hero):
    @wraps(hero)
    def release_skill(*skill, **skills):
        print(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
        return hero(*skill, **skills)
    return release_skill


@release_skills
def hero(name, skill):
    return (name + '-->'+'释放技能:'+ skill)


print(hero('关羽', 'fire'))
print(hero.__name__)
  • 上面的代码用到了wraps(),然后我们运行一下看下结果函数是否被改变
(yiluo) ➜  Code python hero.py
2019-12-12 11:25:38
关羽-->释放技能:fire
hero
  • 函数依旧是hero,看来是完美解决了这个问题
  • @Python 提供的语法糖,语法糖指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用
3.property 装饰器
#!/usr/bin/env python3

class Animal:
    def __init__(self):
        self.age = 3


if __name__ == "__main__":
    cat = Animal()
    print(cat.age)
    cat.age = 'age'
    print(cat.age)
  • 执行结果
➜  code python3 demo.py
3
age
  • 以看到如果 age 属性值可以被公开访问,用户赋值为字符串,很明显这不符合实际情况
#!/usr/bin/env python3

class Animal:
    def __init__(self):
        self.__age = 3
    def get_age(self):
        return self.__age
    def set_age(self, value):
        if isinstance(value, int):
            self.__age = value
        else:
            raise ValueError


if __name__ == "__main__":
    cat = Animal()
    print(cat.get_age)
    cat.set_age('age')
  • 执行结果
Traceback (most recent call last):
  File "demo.py", line 18, in <module>
    cat.set_age('age')
  File "demo.py", line 12, in set_age
    raise ValueError
ValueError
  • @property 装饰器可以将一个方法变成一个属性来使用,通过 @property 装饰器可以获得和修改对象的某一个属性。
  • 使用 @property 装饰器的方法如下:
    1.只有 @property 表示只读
    2.同时有 @property 和 @.setter 表示可读可写
    3.同时有 @property、@
    .setter、和 @.deleter 表示可读可写可删除
    4.@property 必须定义在 @
    .setter 的前面
    5.类必须继承 object 父类,否则 @property 不会生效
#!/usr/bin/env python3

class Animal:
    def __init__(self):
        self.__age = 3
    @property
    def age(self):
        return self.__age
    @age.setter
    def age(self, value):
        if isinstance(value, int):
            self.__age = value
        else:
            raise ValueaError
    @age.deleter
    def age(self):
        print('delete age')
        del self.__age

if __name__ == "__main__":
    cat = Animal()
    print(cat.age)
    cat.age = 6
    print(cat.age)
    del cat.age
    print(cat.age)
  • 执行结果
➜  code python3 demo.py
3
6
delete age
Traceback (most recent call last):
  File "demo.py", line 26, in <module>
    print(cat.age)
  File "demo.py", line 8, in age
    return self.__age
AttributeError: 'Animal' object has no attribute '_Animal__age'
  • 从这个简单的例子中我们可以发现 age 由一个函数转变为一个属性,并且通过增加一个 setter 函数的方式来支持 age 的设置。通过 property 和 setter ,可以有效地实现 get_age(获取对象的属性) 和 set_age(设置对象的属性)这两个操作,而不需要直接将内部的 __age 属性暴露出来,同时可以在 setter 函数中对设置的参数进行检查,避免了直接对 __age 内部属性进行赋值的潜在风险

欢迎下方【戳一下】【点赞】
Author:伊洛Yiluo
愿你享受每一天,Just Enjoy !

相关文章

  • Python11--装饰器

    1.装饰器定义 装饰器本质上是一个函数,可以接受一个函数作为参数 2.装饰器简单的例子 承接之前的内容,英雄释放火...

  • 装饰器

    """@装饰器- 普通装饰器- 带参数的装饰器- 通用装饰器- 装饰器装饰类- 内置装饰器- 缓存装饰器- 类实现...

  • typescript 五种装饰器

    装饰器类型 装饰器的类型有:类装饰器、访问器装饰器、属性装饰器、方法装饰器、参数装饰器,但是没有函数装饰器(fun...

  • python——装饰器详解

    一、装饰器概念 1、装饰器 装饰器:一种返回值也是一个函数的函数,即装饰器。 2、装饰器目的 装饰器的目的:装饰器...

  • Python装饰器

    Python装饰器 一、函数装饰器 1.无参装饰器 示例:日志记录装饰器 2.带参装饰器 示例: 二、类装饰器 示例:

  • Python中的装饰器

    Python中的装饰器 不带参数的装饰器 带参数的装饰器 类装饰器 functools.wraps 使用装饰器极大...

  • 装饰器

    装饰器 decorator类装饰器 带参数的装饰器 举例(装饰器函数;装饰器类;有参与无参) https://fo...

  • TypeScript装饰器

    前言 装饰器分类 类装饰器 属性装饰器 方法装饰器 参数装饰器需要在tsconfig.json中启用experim...

  • python之装饰器模版

    装饰器的作用:装饰器即可以装饰函数也可以装饰类。装饰器的原理:函数也是对象 1.定义装饰器 2.使用装饰器假设de...

  • 装饰器实验

    装饰器实验 说明 ts内包含了四个装饰器,类装饰器、属性装饰器、函数装饰器、参数装饰器,本文中测试一下其的使用。 ...

网友评论

    本文标题:Python11--装饰器

    本文链接:https://www.haomeiwen.com/subject/ebiirktx.html