@property 装饰器
使用 property 实现获取器、设置器和删除器。
@property 装饰器 是 CoddyKit 上的免费 Python Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Python Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Python Academy 课程共包含 4 节课。
简介
@property 会将方法转换为可读属性。@setter 和 @deleter 完成受控访问模式。
为什么使用 @property
Python 不使用 Java 风格的 getX()/setX(),而是使用 @property。访问方式看起来像属性:obj.value,而不是 obj.get_value()。
class Circle:
def __init__(self, r): self._r = r
@property
def radius(self): return self._r
c = Circle(5)
print(c.radius) # no ()计算属性
@property 方法会在需要时即时计算。每次访问 obj.area 时都会重新计算,无需存储值。
import math
class Circle:
def __init__(self, r): self._r = r
@property
def area(self): return math.pi * self._r**2
c = Circle(5)
print(round(c.area, 2))属性设置器
@property_name.setter 会添加设置器。现在,c.radius = 10 会调用设置器方法。
class Circle:
def __init__(self, r): self._r = r
@property
def radius(self): return self._r
@radius.setter
def radius(self, val):
if val <= 0: raise ValueError('radius must be positive')
self._r = val
c = Circle(5)
c.radius = 10
print(c.radius)属性删除器
@property_name.deleter 用于处理 del obj.attr。它适合放置清理逻辑。
class User:
def __init__(self, name): self._name = name
@property
def name(self): return self._name
@name.deleter
def name(self): del self._name
u = User('Alice')
del u.name
print(hasattr(u, '_name'))只读属性
只定义 getter,不定义 setter。尝试赋值时会引发 AttributeError。
class Const:
def __init__(self, v): self._v = v
@property
def value(self): return self._v
c = Const(42)
print(c.value)
try: c.value = 99
except AttributeError as e: print(e)带验证的属性
设置器是验证数据的理想位置——在存储数据前检查类型、范围或格式。
class BoundedInt:
def __init__(self, lo, hi): self.lo,self.hi=lo,hi; self._v=lo
@property
def value(self): return self._v
@value.setter
def value(self, v):
if not self.lo <= v <= self.hi:
raise ValueError(f'{v} out of [{self.lo},{self.hi}]')
self._v = v
b = BoundedInt(0, 10)
b.value = 5
print(b.value)使用 property 进行缓存
将 @property 与缓存值结合起来,只计算一次并进行记忆化。
class Expensive:
_cache = None
@property
def result(self):
if self._cache is None:
self._cache = sum(range(1000))
return self._cache
e = Expensive()
print(e.result)
print(e.result)cached_property(Python 3.8+)
@functools.cached_property 只计算一次属性,并将结果存储为实例属性,不会重复计算。
from functools import cached_property
import math
class Circle:
def __init__(self, r): self.r = r
@cached_property
def area(self): return math.pi * self.r**2
c = Circle(5)
print(round(c.area, 2))Property 与 __slots__
__slots__ 会禁止创建任意属性并节省内存。属性可以添加逻辑。两者可以互相配合。
class Point:
__slots__ = ('_x', '_y')
def __init__(self, x, y): self._x,self._y=x,y
@property
def x(self): return self._x
p = Point(1, 2)
print(p.x)何时使用 @property
在以下情况下请使用 @property:需要验证、计算值,或在更改内部实现的同时保持向后兼容。
# Before: class Person:
# def __init__(self, age): self.age = age
# After: add validation without changing caller code
class Person:
def __init__(self, age): self.age = age
@property
def age(self): return self._age
@age.setter
def age(self, v):
if v < 0: raise ValueError('negative age')
self._age = v
p = Person(30)
print(p.age)快速检查
尝试为只读 @property(未定义 setter)赋值时会发生什么?
回顾
@property:将 getter 转换为属性访问。@name.setter 添加写入支持。@name.deleter 添加删除支持。@cached_property 只计算一次。设置器用于数据验证。
继续学习
进步非常出色!请继续学习,掌握下一个概念。
常见问题解答
「@property 装饰器」课时是免费的吗?
是的 — 「@property 装饰器」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Python Academy 课程的其余内容,请升级到 CoddyKit PRO。 Python Academy 课程共包含 4 节课。
「@property 装饰器」这节课中我会学到什么?
使用 property 实现获取器、设置器和删除器。 你通过在浏览器中直接运行的动手代码来练习 Python Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Python Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Python Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「@property 装饰器」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Python Academy 课中编写并运行代码吗?
能。每节 Python Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 作为一等对象的函数
- 编写自定义装饰器
- @property 装饰器
- @classmethod 与 @staticmethod