Python 中的 @property:像访问属性一样调用方法

发布时间:2026/5/19 21:49:33

Python 中的 @property:像访问属性一样调用方法 # Python 中的 property像访问属性一样调用方法 在写类的时候我们经常会遇到一个问题 对象的属性如果可以被随便修改就可能出现一些不合理的数据。 比如一个人的年龄 python class Person: def __init__(self, age): self.age age然后创建对象person1Person(-18)print(person1.age)这时候程序是可以正常运行的但是很明显不合理。因为年龄不可能是负数。再比如学生成绩classStudent:def__init__(self,score):self.scorescore创建对象student1Student(100)print(student1.score)一开始这样写没什么问题。但是如果外界可以随便修改student1.score-100那就会出现不合理的数据。所以问题来了Python 有没有像 Java 一样可以把属性保护起来然后只暴露指定的接口让外界调用呢答案是有的。在 Python 中我们可以使用property装饰器来控制属性的访问。一、为什么需要属性访问控制如果一个属性可以被外界随便赋值那么数据就可能变得不安全。比如person1Person(-18)这个对象虽然创建成功了但是-18这个年龄明显是不合理的。我们希望在给age赋值的时候能够先判断一下ifage0orage120:raiseValueError(不合理的年龄)如果年龄不合理就直接抛出异常。二、使用 property 定义属性完整代码如下classPerson:def__init__(self,age):self.ageagepropertydefage(self):returnself._ageage.setterdefage(self,age):ifage0orage120:raiseValueError(不合理的年龄)self._ageage person1Person(18)print(person1.age)这段代码中最重要的部分就是propertydefage(self):returnself._ageproperty的作用是把一个方法变成属性一样来访问。也就是说虽然age本质上是一个方法defage(self):returnself._age但是我们调用的时候不需要写成person1.age()而是可以直接写person1.age看起来就像是在访问普通属性一样。三、使用 setter 控制赋值下面这段代码用来控制给age赋值age.setterdefage(self,age):ifage0orage120:raiseValueError(不合理的年龄)self._ageage当我们执行self.ageage或者person1.age18实际上都会自动调用这个 setter 方法。所以在赋值之前程序会先判断年龄是否合法ifage0orage120:raiseValueError(不合理的年龄)如果年龄小于0或者大于120就会抛出异常。如果年龄合理才会真正赋值self._ageage四、为什么使用 _age在代码中真正保存年龄的属性是self._age而不是self.age这是因为self.age已经被property和age.setter接管了。如果在 setter 里面继续写self.ageage就会再次调用 setter导致无限递归。所以我们用self._ageage来真正保存数据。这里的_age前面有一个下划线表示这是一个内部使用的属性不建议外界直接访问。五、创建对象时发生了什么当我们创建对象person1Person(18)会先执行构造方法def__init__(self,age):self.ageage这里的self.ageage并不是简单地创建一个普通属性。因为类里面已经定义了age.setterdefage(self,age):所以这句代码会自动调用 setter 方法。也就是说创建对象的时候年龄就已经被检查了一遍。如果写成person1Person(-18)就会抛出异常ValueError:不合理的年龄这样就避免了创建出不合理的对象。六、读取属性时发生了什么当我们执行print(person1.age)这里的.age其实不是直接访问属性而是在调用这个方法propertydefage(self):returnself._age只不过property让它看起来像普通属性一样。所以person1.age本质上相当于调用了 getter 方法。七、property 的好处使用property有几个好处可以像访问普通属性一样访问方法可以在赋值时增加数据校验可以保护对象内部数据可以让代码更加安全对外使用简单对内逻辑可控比如外界仍然可以这样写person1.age也可以这样赋值person1.age20但是赋值的时候程序会自动帮我们检查数据是否合法。八、总结property装饰器可以把方法伪装成属性来访问。它通常和 setter 一起使用propertydefage(self):returnself._ageage.setterdefage(self,age):ifage0orage120:raiseValueError(不合理的年龄)self._ageage这样做的好处是既保留了属性访问的简洁写法又可以在内部控制数据是否合法。简单来说property负责读取属性。属性名.setter负责设置属性。在这个例子中我们通过property和age.setter让age属性不能被随便设置成不合理的值。这就是 Python 中属性访问控制的一种常见写法。

相关新闻