在python中计算属性的时间和频率是多少?

时间:2012-09-06 20:01:02

标签: python

  

可能重复:
  python: are property fields being cached automatically?

由于担心python中属性的效率,我想知道它们被调用的时间和频率。

使用一个简单的例子,假设我是一个子类namedtuple,我有类似的东西:

from collections import namedtuple
from math import pi

class Circle (namedtuple('Circle', 'x, y, r')):
    __slots__ = ()

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

unitCircle = Circle(0, 0, 1.0)
print 'The area of the unit circle is {0} units'.format(unitCircle.area)

我假设在第一次调用区域之前不会计算该区域,但是一旦调用该区域,该值是否会被缓存,直到某些内容发生变化或每次调用它时是否重新计算?

换句话说,如果我有一个属性(不像这个)计算相对昂贵并且将被重复使用,我应该让它成为属性,还是更有效地将它存储为值并明确地当它真的需要更新时才能解决它?

2 个答案:

答案 0 :(得分:9)

除非您明确地执行属性,否则不会缓存属性,因此每次访问该属性时都会运行代码。尝试:

@property
def area(self):
    try:
        return self._area
    except AttributeError:
        area = pi*self.r**2
        self._area = area
        return area

如果您希望偶尔重新计算按需价值,请执行以下操作:

@property
def area(self):
    try:
        return self._area
    except AttributeError:
        self.recalc_area()
        return self._area

def recalc_area(self):
    self._area = pi*self.r**2

或者,如果您想更自动地执行此操作:

@property
def area(self):
    try:
        return self._area
    except AttributeError:
        area = pi*self.radius**2
        self._area = area
        return area

@property
def radius(self):
    return self._radius

@radius.setter
def radius(self, radius):
    try:
        del self._area
    except AttributeError:
        pass
    self._radius = radius

答案 1 :(得分:1)

加载类时,将对python中的装饰器(如@property)进行评估。有时候对类产生的影响将包括额外的函数,但装饰器本身只运行一次。