关于如何在Python中使用属性功能的实际示例?

153 投票
10 回答
75413 浏览
提问于 2025-04-16 19:18

我对如何在Python中使用@property很感兴趣。我看过Python的官方文档,里面的例子在我看来只是一些玩具代码:

class C(object):
    def __init__(self):
        self._x = None

    @property
    def x(self):
        """I'm the 'x' property."""
        return self._x

    @x.setter
    def x(self, value):
        self._x = value

    @x.deleter
    def x(self):
        del self._x

我不太明白把_x用属性装饰器包裹起来有什么好处。为什么不直接这样实现呢:

class C(object):
    def __init__(self):
        self.x = None

我觉得属性这个功能在某些情况下可能会有用。但是具体什么时候会用到呢?能不能给我一些实际的例子?

10 个回答

22

看看这篇文章,里面有很实用的内容。简单来说,它讲的是在Python中,你通常可以不需要明确地写获取器和设置器方法。如果你在某个阶段真的需要这些功能,可以用property来轻松实现。

85

一个简单的用法是设置一个只读的实例属性。在Python中,如果一个变量名以一个下划线_x开头,通常表示这个变量是私有的(只供内部使用)。但有时候我们希望能够读取这个实例属性,而不想修改它,这时候我们可以使用property来实现:

>>> class C(object):

        def __init__(self, x):
            self._x = x

        @property
        def x(self):
            return self._x

>>> c = C(1)
>>> c.x
1
>>> c.x = 2
AttributeError        Traceback (most recent call last)

AttributeError: can't set attribute
97

其他例子包括对设置的属性进行验证或过滤(确保它们在合理范围内或是可以接受的),以及对复杂或快速变化的内容进行懒惰计算。

属性背后隐藏的复杂计算:

class PDB_Calculator(object):
    ...
    @property
    def protein_folding_angle(self):
        # number crunching, remote server calls, etc
        # all results in an angle set in 'some_angle'
        # It could also reference a cache, remote or otherwise,
        # that holds the latest value for this angle
        return some_angle

>>> f = PDB_Calculator()
>>> angle = f.protein_folding_angle
>>> angle
44.33276

验证:

class Pedometer(object)
    ...
    @property
    def stride_length(self):
        return self._stride_length

    @stride_length.setter
    def stride_length(self, value):
        if value > 10:
            raise ValueError("This pedometer is based on the human stride - a stride length above 10m is not supported")
        else:
            self._stride_length = value

撰写回答