5

可能重复:
python:属性字段是否被自动缓存?

作为对 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)

我假设直到第一次调用该区域时才计算该区域,但是一旦调用该区域,该值是否会缓存到某些内容发生更改或每次调用时都会重新计算?

换句话说,如果我有一个属性(与这个不同)计算起来相对昂贵并且会被重复使用,我应该让它成为一个属性,还是将它存储为一个值并在何时显式计算它更有效?它真的需要更新吗?

4

2 回答 2

14

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

@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
于 2012-09-06T20:02:23.180 回答
1

python 中的装饰器(如@property)在加载类时得到评估。有时对类产生的影响会包括额外的功能,但装饰器本身只运行一次。

于 2012-09-06T20:07:20.803 回答