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 など) は、クラスがロードされるときに評価されます。クラスへの結果として追加の関数が含まれることがありますが、デコレータ自体は 1 回しか実行されません。

于 2012-09-06T20:07:20.803 に答える