Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中何时以及多久计算一次属性?_Python - Fatal编程技术网

在python中何时以及多久计算一次属性?

在python中何时以及多久计算一次属性?,python,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*

可能重复:

考虑到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)
@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.r**2
        self._area = area
        return area
如果希望能够偶尔根据需要重新计算值,请执行以下操作:

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)
@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

python中的修饰符(如@property)在类加载时进行求值。有时,对类产生的效果将包括额外的函数,但装饰器本身只运行一次。

您不必选择或。如果尚未加载,您可以拥有缓存自身的属性,然后可以根据需要定期重新缓存。谢谢。因此,这听起来像是一个基本属性,例如,对于计算成本较低或很少引用的值,该示例是很好的。对于计算量大且重复引用而不更改的值,提供更复杂的缓存似乎是明智的。这似乎是一个很好的分析。您甚至可以创建另一个decorator来封装
属性
,从而自动化缓存过程。我在网上看到过一些例子,甚至一些库,它们使依赖项链接过程更加明确,例如area>radius。