python基础七:装饰器property用法及使用它重构代码时的应用实例

举报
橙子园 发表于 2022/05/25 23:57:51 2022/05/25
【摘要】 一、装饰器   我们知道装饰器可以将所需要的函数作为对象返回给需要用此函数处理的对象。而property装饰器则是将一个函数或者方法成为一个属性以供使用。@property这种语法糖形式简化了装饰器的使...

一、装饰器

  我们知道装饰器可以将所需要的函数作为对象返回给需要用此函数处理的对象。而property装饰器则是将一个函数或者方法成为一个属性以供使用。@property这种语法糖形式简化了装饰器的使用。

二、引导

  在面向对象类型的语言中访问修改类中的属性时通常会自己写set或者get函数,对输出结果进行修饰或者对输入进行合法化检查。然而python可以提供一种优美的更直观的方法就是使用装饰器@property。

三、用法

实例:对属性进行正整数检查

class Inter:

    def __init__(self, value=0):
        self.inter = value

    def get_int(self):
        """
        将输出转化为字符串
        :return:
        """

        return str(self.inter)

    def set_int(self, value):
        if(value < 0) | (not isinstance(value, int)):
            raise ValueError('inter is error.')
        self.inter = value
        return self.inter

a = Inter()
a.set_int(3)
print(a.get_int())

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

  这样写是不是很不直观,所以我们采用property来写,并使用语法糖@property

class Inter:

    def __init__(self, value=0):
        self._inter = value

    @property
    def inter(self):
        """
        将输出转化为字符串
        :return:
        """

        return str(self._inter)

    @inter.setter
    def inter(self, value):
        if(value < 0) | (not isinstance(value, int)):
            raise ValueError('inter is error.')
        self._inter = value
        return self._inter

a = Inter()
a.inter = 3
print(a.inter)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

四、重构代码的应用实例

  很久以前,Python程序员Tom写了一个代表金钱的类。他的实现的形式下面这样:

# 首个版本
class Money:
    def __init__(self, dollars, cents):
        self.dollars = dollars
        self.cents = cents

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

  这个类后来被打包到一个公共库里,慢慢地被不同的应用使用。公司另一个团队中的Bob是这样使用Money类的:

# 创建一个money对象
money = Money(34, 1)
print("{} dollars and {} cents.".format(money.dollars, money.cents))
# 修改money类的属性
money.dollars = 23
money.cents = 2
print("{} dollars and {} cents.".format(money.dollars, money.cents))

结果:
    34 dollars and 1 cents.
    23 dollars and 2 cents.

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

  一段时间后,公司业务变化原来的money只需要记录美分。pm找到开发,然而Tom却离职了,只能找到刚接手的Jerry。Jerry看过代码后说没问题,他是这样改的:

# 第二个版本
class Money:
    def __init__(self, dollars, cents):
        self.total_cents = dollars * 100 + cents

  
 
  • 1
  • 2
  • 3
  • 4

  改完后Jerry突然想到:如果很多业务部门引用Money类的话,每一处都必须要调整。幸好他是一个机智的少年,知道装饰器property的使用方法,马上做出如下的修改。

# 最终版本
class Money:
    def __init__(self, dollars, cents):
        self.total_cents = dollars * 100 + cents

    # dollars使用property装饰器的输入、输出
    @property
    def dollars(self):
        return self.total_cents // 100;
    @dollars.setter
    def dollars(self, new_dollars):
        self.total_cents = 100 * new_dollars + self.cents

    # cents使用property装饰器的输入、输出
    @property
    def cents(self):
        return self.total_cents % 100;
    @cents.setter
    def cents(self, new_cents):
        self.total_cents = 100 * self.dollars + new_cents


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

上面代码使用@property装饰器定义了dollars、cents属性(相当于get函数),还利用@dollars.setter、@cents.setter创建了一个setter(相当于set函数)。

Jerry对刚才自己机智的行为很是满意,奖励自己晚餐一个大大的鸡腿,而另一个团队Bob并没有感觉到任何的变化。

文章来源: blog.csdn.net,作者:橙子园,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/Chenftli/article/details/89762364

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。