@Python中的属性速度开销

@Python中的属性速度开销,python,performance,properties,object-design,Python,Performance,Properties,Object Design,我试图理解Python中@property decorator的实用性。具体来说,我使用如下属性设置了一个类: 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 我还设置了一个没有提供

我试图理解Python中@property decorator的实用性。具体来说,我使用如下属性设置了一个类:

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
我还设置了一个没有提供相同功能的属性的类:

class B(object):
    def __init__(self, x):
        self._x = x
我创建以下各项的一个实例:

a = A(10)
b = B(10)
在iPython中运行%timeit会产生以下结果

%timeit a.x
%timeit b._x
1000000个循环,最佳3个:每个循环213纳秒

%timeit a.x = 15
%timeit b._x = 15
10000000个循环,最佳3个:每个循环67.9纳秒

%timeit a.x = 15
%timeit b._x = 15
1000000个循环,最好3个:每个循环257纳秒

%timeit a.x = 15
%timeit b._x = 15
10000000个循环,最佳3个:每个循环89.7纳秒

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

显然,如果您要以显著的频率与对象交谈,@property和@setter装饰器是次等的。我的问题很简单,为什么要使用它?我很想听听人们对这些装饰器的使用案例。谢谢。

简单的答案是基本属性不使用
属性。它们对于存储或检索时需要附加逻辑的属性非常有用。例如,具有从其他属性或需要错误检查或其他专门过滤的属性派生的值的属性。使用
property
s可以让您以一种点菜式的方式使用其他语言中通用的setter/getter模式,而不是强制使用冗长的样板文件。

如果属性非常简单,请不要使用
property
。你不需要它<代码>属性
用于获取和设置属性需要执行更多操作的情况,例如,如果涉及计算:

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

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

中讨论了使用属性的所有优点。正如你所发现的,这是以速度上的一些小损失为代价的。如果不考虑可用性、灵活性或其他任何因素,就用额外几十纳秒的成本来衡量“劣质”是愚蠢的。很少需要对属性访问进行微优化。在少数情况下,当访问一个不变的属性是一个瓶颈时,您通常希望将其复制到一个局部变量,并在循环中访问该变量,因此无论属性访问的速度有多快都无关紧要。如果您正在编写真正重要的代码,那么可能不应该用Python编写。