Python property 函数
上次修改时间:2025 年 4 月 11 日
本综合指南探讨了 Python 的 property
函数,该函数创建具有 getter、setter 和 deleter 方法的托管属性。我们将介绍基本用法、装饰器语法和实际示例。
基本定义
property
函数返回一个 property 属性。它提供了一种使用方法封装实例属性访问的方式。这使得数据验证、计算属性和只读属性成为可能。
主要特点:接受可选的 getter、setter、deleter 和文档字符串参数。返回一个 property 对象,该对象在访问时使用这些方法。它是 Python 中的内置描述符类型。
基本 Property 用法
这是一个简单的用法示例,展示了如何为温度类创建一个带有验证的 property。该 property 确保温度保持在绝对零度以上。
class Temperature: def __init__(self, celsius): self._celsius = celsius def get_celsius(self): return self._celsius def set_celsius(self, value): if value < -273.15: raise ValueError("Temperature below absolute zero") self._celsius = value celsius = property(get_celsius, set_celsius) temp = Temperature(25) print(temp.celsius) # 25 temp.celsius = 30 print(temp.celsius) # 30 try: temp.celsius = -300 # Raises ValueError except ValueError as e: print(e)
此示例演示了如何使用单独的 getter 和 setter 方法创建 property。该 property 确保温度值在物理上有效,同时保持一个干净的接口。
_celsius
命名约定表明它是一个受保护的属性。用户与 celsius
property 交互,而不是与属性交互。
Property 装饰器语法
Python 的装饰器语法提供了一种更简洁的方式来定义 property。此示例演示了使用装饰器的相同温度类。
class Temperature: def __init__(self, celsius): self._celsius = celsius @property def celsius(self): return self._celsius @celsius.setter def celsius(self, value): if value < -273.15: raise ValueError("Temperature below absolute zero") self._celsius = value temp = Temperature(25) print(temp.celsius) # 25 temp.celsius = -100 print(temp.celsius) # -100
装饰器语法更具可读性,并将相关方法组合在一起。@property
装饰器创建 getter,而 @celsius.setter
创建 setter。
这种方法在现代 Python 代码中更受欢迎,因为它清楚地表明了哪些方法属于该 property。
只读 Property
Property 可以通过省略 setter 来创建只读属性。此示例显示了一个具有计算的只读面积 property 的圆形类。
import math class Circle: def __init__(self, radius): self.radius = radius @property def area(self): return math.pi * self.radius ** 2 circle = Circle(5) print(circle.area) # 78.53981633974483 try: circle.area = 100 # Raises AttributeError except AttributeError as e: print("Can't set area:", e)
area
property 从半径计算得出,不能直接设置。尝试设置它会引发 AttributeError
。
此模式对于仅当其源属性更改时才应更改的派生属性很有用。
带有 Deleter 的 Property
Property 还可以定义 deleters 以进行清理操作。此示例显示了一个具有基于 property 的资源管理的文件处理程序类。
class FileHandler: def __init__(self, filename): self._filename = filename self._file = open(filename, 'r') @property def file(self): return self._file @file.deleter def file(self): if self._file: self._file.close() self._file = None handler = FileHandler('example.txt') print(handler.file.read(10)) del handler.file # Closes the file
deleter 确保在删除 property 时进行适当的资源清理。这比依赖 __del__
或上下文管理器更明确。
该 property 提供了对文件对象的受控访问,同时保持了在需要时正确关闭它的能力。
动态 Property
Property 可以从其他属性动态计算值。此示例显示了一个具有动态宽度/高度 property 的矩形类。
class Rectangle: def __init__(self, x1, y1, x2, y2): self.x1, self.y1 = x1, y1 self.x2, self.y2 = x2, y2 @property def width(self): return abs(self.x2 - self.x1) @width.setter def width(self, value): if value <= 0: raise ValueError("Width must be positive") self.x2 = self.x1 + value @property def height(self): return abs(self.y2 - self.y1) @height.setter def height(self, value): if value <= 0: raise ValueError("Height must be positive") self.y2 = self.y1 + value rect = Rectangle(0, 0, 10, 20) print(rect.width, rect.height) # 10 20 rect.width = 15 print(rect.width) # 15
宽度和高度 property 是从坐标计算得出的,但也可以设置,这将更新坐标。这保持了数据一致性。
当您想要呈现相同底层数据的不同视图,同时保持一切同步时,此方法非常有用。
最佳实践
- 用于封装: 将实现细节隐藏在 property 之后
- 首选装饰器语法: 为了更简洁、更具可读性的代码
- 文档 property: 包括解释行为的文档字符串
- 在 setter 中验证: 确保数据保持一致
- 考虑性能: 计算的 property 可能会影响性能
资料来源
作者
列出所有 Python 教程。