【python】@property装饰器

发布时间 2023-12-08 10:51:29作者: TesterBenja

@property

介绍:@property是一个内置的装饰器,用于将一个方法变成属性调用。让方法可以像实例属性那样进行访问,这样可以保证对象状态的封装性,同时,将数据的“获取”和“修改”集成到一处处理,提高代码的可读性和可维护性。

通过对比,解释@property的意义:

class Person:
    def __init__(self, name):
        self._name = name

p = Person("Alice")
print(p._name)  # Alice
p._name = "Bob"
print(p._name)  # Bob

这是一个非常简单的类,我们可以直接通过访问_name属性来获取及修改name。

但存在一些问题:
1.对于类的用户来说,他们并不应该需要关心名字是存储在_name这个属性中的,用户只关心自己能够获取及修改这个人的名字就可以了。如果有一天,我们想改变名字的存储方式,例如名字需要存成全大写,类的用户可能就需要修改他们的代码来适配这个变化。
2.我们无法对设置名字的操作做出限制。比如说,我们希望名字必须是一个非空字符串,但在目前的代码下用户是完全可以给人设置一个空字符串作为名字的。

看看如何用@property来解决上述问题:

class Person:
    def __init__(self, name):
        self._name = name

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        if not value:
            raise ValueError("Name cannot be empty")
        self._name = value

p = Person("Alice")
print(p.name)  # Alice
p.name = "Bob"
print(p.name)  # Bob

此时的name就变成了一个对外的属性,而用户不再需要关心内部是如何存储的。同时,我们的类也可以自由地修改内部实现,同时不会影响到类的用户。同时,我们也可以在setter方法中,设定一些条件来限制设置的值。

即使有一天我们改变了名字的存储方式:

    @name.setter
    def name(self, value):
        if not value:
            raise ValueError("Name cannot be empty")
        self._name = value.upper()    #改为大写存储

类的用户像之前一样使用就可以了,不会受到影响。

总结来说,@property能够让我们更好的封装内部实现,对类用户提供更加简单清晰的接口,同时可以在需要的时候对设置的值做出限制。