python笔记 私有相关的property装饰器

97 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情

0 环境

  • 编辑器:pycharm或者vscode
  • 系统版本:windows10
  • python版本:3.9.6

1 单下划线

单下划线告诉我们是私有的,但是解释器不会做出任何的处理。也就说:比如我实例化类时,初始化时,赋值self._var = 12,然后我实例._var = 100,重新赋值,可以赋值,继续,现在就是要确定我实例中_var是实例变量,打印实例.dict,会发现确实是实例变量,那么也就是说,对于解释器来说,它是共有的,而单下划线的提供者会告诉使用者们,我相信你是好人,会遵守我们的约定/惯例,默认它是私有的,不要乱动。

2 @property

@property装饰器会将一个只有self(注意:是只有一个self,没有其他参数)参数的函数,变成了一个属性,该属性值为方法的属性值。使用的话,只需要实例.该方法即可(方法不要加双括号,当变量调用)。如下图:

image.png

现在我想要对入参的值,进行判断,如果它不是int类型,且值的大小在我指定的范围,我就返回值。常规方式,是不是先定义set_number()方法,然后在里面编写相依逻辑,最终将__number付给self,最后在通过方法number()得到__number的值。也就是说,我们要两个方法,一个用来设置值,一个得到值。而有么有简化的方式呢,装饰器可以帮助我们。如下代码:

首先设置值的方法放在得到值的方法的下面(@property要在上面,所有得到值的方法要放在上面的原因),且这两个方法名要一样的,设置值地方要加方法.setter。这样方法就转了属性。如下main里的Door1实例化,我赋的值大于100或者不是整型,赋值是不生效的。当赋值符合条件,我直接赋值给实例.xxx,打印实例.xxx,是不是很舒服。

class Door1:
    def __init__(self, number, status):
        self.__number = number
        self.__status = status

    def open(self):
        self.__status = "opening"

    @property
    def status(self):
        return self.__status

    @property
    def value(self):
        return self.__number

    @value.setter
    def value(self, number):
        # 先判断number是否int类型,number大于0 小于100
        if isinstance(number, int) and number > 0 and number < 100:
            self.__number = number

if __name__ == '__main__':
    door = Door1(50, "closed")
    print(door.value)
    door.value = 1000
    print(door.value)
    door.value = 80
    print(door.value)
    door.value = "12"
    print(door.value)

image.png

3 总结

property装饰器获取、设置、删除(这里和设置的方式类似,不同点它是del 实例.xxxx)。当想要用该装饰器的设置,记住:获取在上/前,设置在下/后,获取和设置同名,获取要加上@property,而设置要加上@同名.setter。使用上和赋值变量一样。