property属性
property
是python中用于定义类属性的一种方法,它允许将方法
伪装成属性
,使得我们可以像 访问普通属性一样访问方法. 通常用于定义只读属性
,或者 通过属性访问来控制属性的设置和获取操作
使用 property
可以帮助你在类中对属性的访问进行更好的控制,而不需要改变属性的访问方式。例如,可以在读取属性时执行一些额外的逻辑,或者在设置属性时进行验证。
基本使用
property
可以通过装饰器或直接调用来实现。下面是两种实现方法。
方法1:使用 property()
函数
class Person:
def __init__(self, name):
self._name = name # 使用前导下划线表示私有属性
# 定义 getter 方法
def get_name(self):
return self._name
# 定义 setter 方法
def set_name(self, value):
if isinstance(value, str):
self._name = value
else:
raise ValueError("名字必须是字符串")
# 定义 property 对象(充当 类属性)
name = property(get_name, set_name) # 这里通过 property 函数创建属性
p = Person("Alice")
print(p.name) # 调用 get_name 方法,输出 "Alice"
p.name = "Bob" # 调用 set_name 方法,将 _name 设置为 "Bob"
print(p.name) # 调用 get_name 方法,输出 "Bob"
方法2:使用 @property
装饰器
通过装饰器的方式更加简洁和常用。
class Person:
def __init__(self, name):
self._name = name # 使用前导下划线表示私有属性
@property
def name(self):
return self._name # 定义 getter
@name.setter
def name(self, value):
if isinstance(value, str):
self._name = value # 定义 setter
else:
raise ValueError("名字必须是字符串")
@name.deleter
def name(self):
print("删除 name 属性")
del self._name # 定义 deleter
p = Person("Alice")
print(p.name) # 调用 getter,输出 "Alice"
p.name = "Bob" # 调用 setter,将 _name 设置为 "Bob"
print(p.name) # 调用 getter,输出 "Bob"
del p.name # 调用 deleter,删除 _name 属性
输出结果:
Alice
Bob
删除 name 属性
解释:
@property: 将一个方法转换为只读属性,这意味着你可以像访问普通属性一样调用这个方法,而不需要加括号。
@property.setter: 用于设置属性值的函数装饰器。它和 @property 搭配使用。
@property.deleter: 用于删除属性的函数装饰器,它定义了当 del 操作符被用于该属性时的行为。
只读属性
如果你只想定义一个只读属性,不希望属性被修改,可以只定义 getter
而不定义 setter
:
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius # 只读属性
circle = Circle(5)
print(circle.radius) # 输出: 5
circle.radius = 10 # 这会抛出 AttributeError,因为没有定义 setter
属性验证
property
可以用于属性的验证逻辑,确保设置的值符合一定条件:
class Rectangle:
def __init__(self, width, height):
self._width = width
self._height = height
@property
def width(self):
return self._width
@width.setter
def width(self, value):
if value > 0:
self._width = value
else:
raise ValueError("宽度必须是正数")
@property
def height(self):
return self._height
@height.setter
def height(self, value):
if value > 0:
self._height = value
else:
raise ValueError("高度必须是正数")
rect = Rectangle(10, 5)
print(rect.width) # 输出: 10
rect.width = -1 # 抛出 ValueError: 宽度必须是正数
总结:
property
提供了一种优雅的方式来控制对类属性的访问,允许我们在获取和设置属性时添加逻辑,而不改变类的外部接口。- 使用
@property
和相关的setter
、deleter
装饰器,可以控制属性的读、写、删操作,使得属性的访问方式更符合自然语言的表达方式。