Python入门——property()函数、装饰器、只读属性、属性验证

发布于:2024-11-02 ⋅ 阅读:(121) ⋅ 点赞:(0)

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 和相关的 setterdeleter 装饰器,可以控制属性的读、写、删操作,使得属性的访问方式更符合自然语言的表达方式。

网站公告

今日签到

点亮在社区的每一天
去签到