7

私のPythonクラスには、最初に呼び出されたときに計算するための作業を必要とするいくつかの変数があります。後続の呼び出しは、事前に計算された値を返すだけです。

ユーザーが実際に必要としない限り、この作業に時間を無駄にしたくありません。では、このユースケースを実装するためのクリーンなPythonの方法はありますか?

私の最初の考えは、property()を使用して関数を最初に呼び出してから、変数をオーバーライドすることでした。

class myclass(object):
    def get_age(self):
        self.age = 21 # raise an AttributeError here
        return self.age

    age = property(get_age)

ありがとう

4

5 に答える 5

14
class myclass(object):
    def __init__(self):
        self.__age=None
    @property
    def age(self):
        if self.__age is None:
            self.__age=21  #This can be a long computation
        return self.__age

アレックスはあなたが使うことができる__getattr__と言いました、これはそれがどのように機能するかです

class myclass(object):
    def __getattr__(self, attr):
        if attr=="age":
            self.age=21   #This can be a long computation
        return super(myclass, self).__getattribute__(attr)

__getattr__()属性がオブジェクトに存在しない場合、つまり、が呼び出されます。初めてアクセスしようとしたときage。毎回age存在するので__getattr__呼ばれない

于 2009-10-21T01:01:54.863 に答える
6

property、あなたが見てきたように、それを上書きすることはできません。次のような少し異なるアプローチを使用する必要があります。

class myclass(object):

    @property
    def age(self):
      if not hasattr(self, '_age'):
        self._age = self._big_long_computation()
      return self._age

__getattr__またはカスタム記述子クラスなどの他のアプローチもありますが、これはより簡単です!-)

于 2009-10-21T01:04:03.470 に答える
4

この問題のPythonクックブックのデコレータは次のとおりです。

class CachedAttribute(object):
    ''' Computes attribute value and caches it in the instance. '''
    def __init__(self, method, name=None):
        # record the unbound-method and the name
        self.method = method
        self.name = name or method.__name__
    def __get__(self, inst, cls):
        if inst is None:
            # instance attribute accessed on class, return self
            return self
        # compute, cache and return the instance's attribute value
        result = self.method(inst)
        setattr(inst, self.name, result)
        return result
于 2009-10-21T09:05:04.997 に答える
2

はい、プロパティを使用できますが、遅延評価は記述子を使用して実行されることもよくあります。例を参照してください。

http://blog.pythonisito.com/2008/08/lazy-descriptors.html

于 2009-10-21T01:02:05.723 に答える
1

この質問はすでに11年前のものであり、Python 3.8以降にはcached_propertyが付属しており、これはこの目的に完全に役立ちます。プロパティは1回だけ計算され、後で使用できるようにメモリに保持されます。

この場合の使用方法は次のとおりです。

class myclass(object):
    @cached_property
    def age(self):
        return 21  #This can be a long computation
于 2021-06-24T06:59:02.050 に答える