装饰器property用法及使用它重构代码时的应用实例

简介:   我们知道装饰器可以将所需要的函数作为对象返回给需要用此函数处理的对象。而property装饰器则是将一个函数或者方法成为一个属性以供使用。@property这种语法糖形式简化了装饰器的使用。 ### 二、引导  在面向对象类型的语言中访问修改类中的属性时通常会自己写set或者get函数,对输出结果进行修饰或者对输入进行合法化检查。然而python可以提供一种优美的更直观的方法就是使用装饰器@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())

  这样写是不是很不直观,所以我们采用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)

四、重构代码的应用实例

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

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

  这个类后来被打包到一个公共库里,慢慢地被不同的应用使用。公司另一个团队中的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.

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

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

  改完后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

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

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

目录
相关文章
|
6月前
【建议】强烈推荐ES6函数自由传参的写法,针对方法体的可扩展性很有帮助
【建议】强烈推荐ES6函数自由传参的写法,针对方法体的可扩展性很有帮助
|
5月前
|
缓存 监控 程序员
Python中的装饰器是一种特殊类型的声明,它允许程序员在不修改原有函数或类代码的基础上,通过在函数定义前添加额外的逻辑来增强或修改其行为。
【6月更文挑战第30天】Python装饰器是无侵入性地增强函数行为的工具,它们是接收函数并返回新函数的可调用对象。通过`@decorator`语法,可以在不修改原函数代码的情况下,添加如日志、性能监控等功能。装饰器促进代码复用、模块化,并保持源代码整洁。例如,`timer_decorator`能测量函数运行时间,展示其灵活性。
50 0
|
2月前
|
JavaScript
代码缺乏装饰?使用ts装饰器来装饰你的代码
该文章详细介绍了TypeScript中的装饰器特性,包括类装饰器、方法装饰器、属性装饰器和参数装饰器的定义与使用方法,并通过具体示例展示了装饰器在实际编码中的应用技巧。
|
5月前
|
数据安全/隐私保护 Python
Python装饰器是高阶函数,用于在不修改代码的情况下扩展或修改函数行为。它们提供可重用性、模块化和无侵入性的功能增强。
【6月更文挑战第20天】Python装饰器是高阶函数,用于在不修改代码的情况下扩展或修改函数行为。它们提供可重用性、模块化和无侵入性的功能增强。例如,`@simple_decorator` 包装`my_function`,在调用前后添加额外操作。装饰器还能接受参数,如`@logged(&quot;INFO&quot;, &quot;msg&quot;)`,允许动态定制功能。
45 6
|
6月前
|
前端开发 JavaScript 安全
对象属性值的黑魔法:ES8的简化语法让你的代码更简洁
对象属性值的黑魔法:ES8的简化语法让你的代码更简洁
|
6月前
|
数据安全/隐私保护 Python
解释装饰器(decorator)的功能和用法。
解释装饰器(decorator)的功能和用法。
53 1
简化对象和函数写法
简化对象和函数写法
37 1
|
6月前
|
存储 C++
【C++】function包装器全解(代码演示,例题演示)
【C++】function包装器全解(代码演示,例题演示)
|
JavaScript 前端开发 Java
ts装饰器-元编程技巧:如何利用装饰器特性开发框架?
ts装饰器-元编程技巧:如何利用装饰器特性开发框架?
|
Java
Java接口概念和语法例子(功能性方法)
比如有三个类。兔子、狗、青蛙这三个类。要定义一个公共游泳方法出来。但是兔子不会这个游泳,那么就不使用这个接口,另外的狗和青蛙会游泳,就会使用这个游泳接口。简单来说,就是谁需要功能接口谁就使用这个功能接口就好了
122 0