关于性能:@property在Python中加速开销

@property speed overhead in Python

本问题已经有最佳答案,请猛点这里访问。

我正在尝试理解python中@property decorator的实用程序。具体来说,我使用如下属性设置了一个类:

1
2
3
4
5
6
7
8
9
10
11
class A(object):
    def __init__(self, x):
        self._x = x

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

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

我还设置了一个没有提供相同功能的属性的类:

1
2
3
class B(object):
    def __init__(self, x):
        self._x = x

我创建每个的实例:

1
2
a = A(10)
b = B(10)

在ipython中运行%timeit会产生以下结果

1
2
%timeit a.x
%timeit b._x

1000000个环路,每个环路最好3:213 ns

10000000个回路,最好是3个:每个回路67.9 ns

1
2
%timeit a.x = 15
%timeit b._x = 15

1000000个环路,每个环路最多3个:257纳秒

10000000个回路,最好是3个:每个回路89.7 ns

显然,@property和@setter修饰符如果您要以很高的频率与对象进行对话,那么它们就比较差了。我的问题是,简单地说,为什么要使用它?我很想听听人们可能拥有的这些装饰师的任何用例。谢谢。


简单的答案是,基本属性不使用property。它们对于存储或检索时需要额外逻辑的属性很有用。例如,具有从其他属性或需要错误检查或其他专门筛选的属性派生的值的属性。使用property允许您使用在其他语言中常见的通用setter/getter模式,而不是强制使用冗长的样板文件。


如果属性很简单,不要使用property。你不需要它。property用于获取和设置属性需要做更多工作的情况,例如,如果涉及计算:

1
2
3
@property
def area(self):
    return math.pi * self.radius**2

当以前简单的__dict__查找突然需要执行额外的工作时,它们特别有用。您可以切换到属性,而无需在每个调用站点添加方法调用括号。