在 Python 中,属性装饰器(@property
) 是一种用于管理类属性访问的高级工具,它可以让你在访问或修改属性时添加自定义逻辑(如数据验证、计算属性等)。
@property
允许你通过属性语法(.
)调用方法,无需显式加括号。
class Celsius:
def __init__(self, temperature=0):
self._temperature = temperature # 内部使用私有变量
@property
def temperature(self):
print("Getting temperature...")
return self._temperature
@temperature.setter
def temperature(self, value):
print("Setting temperature...")
if value < -273.15:
raise ValueError("Temperature below absolute zero is impossible")
self._temperature = value
# 使用示例
c = Celsius(25)
print(c.temperature) # 输出: Getting temperature... 25
c.temperature = 30 # 输出: Setting temperature...
# c.temperature = -300 # 抛出 ValueError
@property
:定义 temperature
的 获取方法(getter)。@temperature.setter
:定义 temperature
的 设置方法(setter)。@temperature.deleter
(可选):定义删除属性的逻辑。如果只定义 @property
而不定义 setter
,则属性为只读。
class Circle:
def __init__(self, radius):
self.radius = radius
@property
def area(self):
return 3.14159 * self.radius ** 2
# 使用示例
circle = Circle(5)
print(circle.area) # 输出: 78.53975
# circle.area = 100 # 报错:AttributeError(没有 setter)
通过 setter
方法,可以在赋值时添加逻辑(如范围检查)。
class Person:
def __init__(self, name):
self.name = name
self._age = 0 # 内部私有变量
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if not 0 <= value <= 120:
raise ValueError("Age must be between 0 and 120")
self._age = value
# 使用示例
p = Person("Alice")
p.age = 30
print(p.age) # 输出: 30
# p.age = 150 # 抛出 ValueError
属性值可以动态计算,而非固定存储。
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
@property
def area(self):
return self.width * self.height
@property
def perimeter(self):
return 2 * (self.width + self.height)
# 使用示例
rect = Rectangle(4, 5)
print(rect.area) # 输出: 20
print(rect.perimeter) # 输出: 18
通过 @property.deleter
定义删除属性时的行为。
class User:
def __init__(self, username, password):
self.username = username
self._password = password
@property
def password(self):
return "******" # 隐藏真实密码
@password.deleter
def password(self):
print("Password is being deleted...")
del self._password
# 使用示例
user = User("admin", "secret123")
print(user.password) # 输出: ******
del user.password # 输出: Password is being deleted...
使用 @property
可以避免手动编写 get_xxx()
和 set_xxx()
方法,使代码更简洁。
# 传统写法(冗余)
class OldStyle:
def __init__(self):
self._value = 0
def get_value(self):
return self._value
def set_value(self, value):
if value < 0:
raise ValueError("Value must be positive")
self._value = value
# 属性装饰器(简洁)
class NewStyle:
def __init__(self):
self._value = 0
@property
def value(self):
return self._value
@value.setter
def value(self, value):
if value < 0:
raise ValueError("Value must be positive")
self._value = value
@property
:替代手动编写 getter/setter
。@property
方法简单,避免耗时操作。_value
),属性方法用公开名称。setter
。@property
确保余额不为负。@property
)。@property
验证用户输入的邮箱格式。我曾走过山,走过水,其实只是借助它们走过我的生命。 —史铁生