商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > Python中的@property像访问属性一样调用方法示例

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

  发布于2026-06-30 阅读(0)

扫一扫,手机访问

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

写类的时候,我们总会碰到一个经典难题:对象的属性如果可以被随意修改,那就很容易出现一些“离谱”的数据。

比如一个人的年龄:

class Person:
    def __init__(self, age):
        self.age = age

然后创建对象:

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

person1 = Person(-18)
print(person1.age)

程序居然正常运行了,但年龄是负数——这显然不合理。

再比如学生成绩:

class Student:
    def __init__(self, score):
        self.score = score

创建对象:

student1 = Student(100)
print(student1.score)

一开始没啥毛病,但如果外界可以随便改:

student1.score = -100

不合理的数据就冒出来了。

那么问题来了:Python 有没有像 Ja va 那样,把属性保护起来,只暴露指定接口让外界调用?

答案当然是有的。在 Python 里,我们可以用 @property 装饰器来控制属性的访问。

一、为什么需要属性访问控制

如果一个属性可以被外界随便赋值,数据安全就无从谈起。

例如:

person1 = Person(-18)

对象是创建成功了,但 -18 这个年龄明显不合理。我们希望在给 age 赋值时,能先判断一下:

if age < 0 or age > 120:
    raise ValueError("不合理的年龄")

如果年龄不合理,直接抛出异常,而不是让错误数据悄悄溜进去。

二、使用 @property 定义属性

完整代码是这样:

class Person:
    def __init__(self, age):
        self.age = age

    @property
    def age(self):
        return self._age

    @age.setter
    def age(self, age):
        if age < 0 or age > 120:
            raise ValueError('不合理的年龄')
        self._age = age

person1 = Person(18)
print(person1.age)

代码里最核心的就是这块:

@property
def age(self):
    return self._age

@property 的作用非常直白:把一个方法变成属性一样来访问

也就是说,虽然 age 本质上是一个方法:

def age(self):
    return self._age

但调用时不需要写成 person1.age(),而是可以直接写 person1.age,看起来就跟访问普通属性一模一样。

三、使用 setter 控制赋值

下面这段代码负责给 age 赋值时的控制:

@age.setter
def age(self, age):
    if age < 0 or age > 120:
        raise ValueError('不合理的年龄')
    self._age = age

当我们执行 self.age = age 或者 person1.age = 18 时,都会自动调用这个 setter 方法。所以赋值之前,程序会先判断年龄是否合法:如果年龄小于 0 或大于 120,就抛出异常;只有合理时,才会真正赋值 self._age = age

四、为什么使用 _age

代码中真正保存年龄的属性是 self._age,而不是 self.age。这是因为 self.age 已经被 @property@age.setter 接管了。如果在 setter 里继续写 self.age = age,就会再次调用 setter,导致无限递归。所以我们用 self._age 来真正存储数据。注意前面的下划线,它表示这是一个内部属性,不建议外界直接访问。

五、创建对象时发生了什么

当我们创建对象:

person1 = Person(18)

会先执行构造方法:

def __init__(self, age):
    self.age = age

这里的 self.age = age 并不是简单地创建一个普通属性,因为类里已经定义了 @age.setter,所以这句代码会自动调用 setter 方法。也就是说,创建对象时年龄就已经被检查了一遍。如果写成 person1 = Person(-18),立刻就会抛出 ValueError: 不合理的年龄,避免了创建出不合理的对象。

六、读取属性时发生了什么

当我们执行 print(person1.age) 时,这里的 .age 其实不是直接访问属性,而是在调用被 @property 装饰的方法:

@property
def age(self):
    return self._age

只不过 @property 让这个调用看起来像访问普通属性一样。本质上相当于调用了 getter 方法。

七、@property 的好处

@property 的好处很明显:

  1. 可以像访问普通属性一样访问方法
  2. 赋值时能自动校验数据
  3. 保护对象内部数据
  4. 让代码更安全
  5. 对外使用简单,对内逻辑可控

外界仍然可以用 person1.age 读取,用 person1.age = 20 赋值,但赋值时程序会自动帮我们检查数据是否合法——再多一层保障。

八、总结

@property 装饰器能把方法伪装成属性来访问。它通常和 setter 配合使用:

@property
def age(self):
    return self._age

@age.setter
def age(self, age):
    if age < 0 or age > 120:
        raise ValueError('不合理的年龄')
    self._age = age

这样做的好处是:既保留了属性访问的简洁写法,又可以在内部控制数据是否合法。

简单来说:

  • @property 负责读取属性。
  • @属性名.setter 负责设置属性。

在这个例子中,我们通过 @property@age.setter,让 age 不能被随便设置成不合理的值——这就是 Python 中属性访问控制的一种常见写法。

本文转载于:https://www.jb51.net/python/364795tx4.htm 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注