dtcms模板 XML解析 LeetCode 程序栈 dataframe printing Semantic UI Pure CSS vue教程 bootstrap后台管理模板 ddos压力测试 河南普通话考试 jq选择第一个子元素 mysql自连接 docker启动命令 python注释 python字典类型 python文件 python怎么下载安装 python语言编程 java抽象类 java编程基础 java获取当前月份 java安装步骤 linux命令行 linuxshell编程 黑帮之地修改器 俄罗斯方块java代码 c语言程序100例 mssql js倒计时 烧饼修改器打不开 京东钱包客户端 list删除指定元素 调试js dnf卡邮件 狮子狗打野天赋 淘新闻下载 苹果电脑怎么收藏网页 达芬奇resolve
当前位置: 首页 > 学习教程  > 编程语言

Python11--装饰器

2020/8/31 14:34:38 文章标签:

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 !


本文链接: http://www.dtmao.cc/news_show_150237.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?