簡體   English   中英

僅在第一次調用變量時進行工作的 Pythonic 方式

[英]Pythonic way to only do work first time a variable is called

我的 Python 類有一些變量需要在第一次調用它們時進行計算。 后續調用應該只返回預先計算的值。

我不想浪費時間做這項工作,除非用戶確實需要它們。 那么有沒有一種干凈的 Pythonic 方式來實現這個用例?

我最初的想法是第一次使用 property() 調用函數,然后覆蓋變量:

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

    age = property(get_age)

謝謝

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__不會被調用

正如您所見, property不會讓您覆蓋它。 您需要使用稍微不同的方法,例如:

class myclass(object):

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

還有其他方法,例如__getattr__或自定義描述符類,但這種方法更簡單!-)

Python Cookbook 中針對此問題的裝飾器:

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

是的,您可以使用屬性,但通常也使用描述符來完成惰性求值,例如:

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

這個問題已經有 11 年的歷史了,python 3.8 及更高版本現在帶有cached_property ,它完美地滿足了這個目的。 該屬性將只計算一次,然后保存在內存中以供后續使用。

在這種情況下如何使用它:

class myclass(object):
    @cached_property
    def age(self):
        return 21  #This can be a long computation

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM