python中的@property

        在python中,@property是一个装饰器,用于将类中的方法转换为属性。通过 @property,你可以将方法的调用方式变为属性访问方式,同时保留方法的内部逻辑,可以使代码更加简洁,易读,并且可以在访问属性时执行一些额外的逻辑。

1. @property 的基本用法

示例:使用 @property 定义只读属性

class Person:
    def __init__(self, name, age):
        self._name = name
        self._age = age

    @property
    def name(self):
        """The name property."""
        return self._name

    @property
    def age(self):
        """The age property."""
        return self._age

# 使用
person = Person("Alice", 30)
print(person.name)  # 输出: Alice
print(person.age)   # 输出: 30

在这个例子中,nameage 是通过 @property 装饰器定义的只读属性。它们的访问方式与普通属性相同,但实际上是调用了方法。

2. 提供 setter 和 deleter 方法

@property 装饰器还可以与 @<property_name>.setter@<property_name>.deleter 装饰器一起使用,分别用于定义属性的设置器(setter)和删除器(deleter)。

示例:定义可读写属性

class Person:
    def __init__(self, name, age):
        self._name = name
        self._age = age

    @property
    def name(self):
        """The name property."""
        return self._name

    @name.setter
    def name(self, value):
        if not isinstance(value, str):
            raise TypeError("Name must be a string")
        self._name = value

    @property
    def age(self):
        """The age property."""
        return self._age

    @age.setter
    def age(self, value):
        if not isinstance(value, int):
            raise TypeError("Age must be an integer")
        if value < 0:
            raise ValueError("Age cannot be negative")
        self._age = value

# 使用
person = Person("Alice", 30)
print(person.name)  # 输出: Alice
print(person.age)   # 输出: 30

person.name = "Bob"
person.age = 35

print(person.name)  # 输出: Bob
print(person.age)   # 输出: 35

在这个例子中:

  • name 属性有一个 setter 方法,用于在设置值时进行类型检查。

  • age 属性也有一个 setter 方法,用于在设置值时进行类型检查和值检查。

3. 定义只读属性

如果你只想让属性可读,而不允许修改,可以只定义 @property,而不定义 setter 方法。

示例:定义只读属性

class Person:
    def __init__(self, name, age):
        self._name = name
        self._age = age

    @property
    def name(self):
        """The name property."""
        return self._name

    @property
    def age(self):
        """The age property."""
        return self._age

# 使用
person = Person("Alice", 30)
print(person.name)  # 输出: Alice
print(person.age)   # 输出: 30

# person.name = "Bob"  # 报错:AttributeError

4. 使用 @property 的好处

  1. 封装性:通过 @property,你可以将方法的实现细节隐藏起来,只暴露属性的接口。

  2. 数据验证:在 setter 方法中,你可以添加逻辑来验证数据的合法性。

  3. 计算属性:可以定义一些动态计算的属性,这些属性的值不是直接存储的,而是在访问时计算。

  4. 兼容性:使用 @property 可以在不改变接口的情况下,将普通属性改为方法,或者将方法改为普通属性。

5. 示例:计算属性

假设你有一个 Rectangle 类,你想定义一个 area 属性,它在访问时动态计算矩形的面积。

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:
            raise ValueError("Width must be positive")
        self._width = value

    @property
    def height(self):
        return self._height

    @height.setter
    def height(self, value):
        if value <= 0:
            raise ValueError("Height must be positive")
        self._height = value

    @property
    def area(self):
        return self._width * self._height

# 使用
rect = Rectangle(5, 10)
print(rect.width)   # 输出: 5
print(rect.height)  # 输出: 10
print(rect.area)    # 输出: 50

rect.width = 7
rect.height = 12
print(rect.area)    # 输出: 84

在这个例子中,area 是一个计算属性,它在访问时动态计算矩形的面积。

6. 总结

  • @property:将方法转换为属性,使方法的调用方式与普通属性相同。

  • @<property_name>.setter:定义属性的设置器方法。

  • @<property_name>.deleter:定义属性的删除器方法。

  • 好处:封装性、数据验证、计算属性、兼容性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

俊昭喜喜里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值