亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Python備忘錄/延遲查找屬性裝飾器

Python備忘錄/延遲查找屬性裝飾器

繁星coding 2019-10-24 11:07:57
最近,我瀏覽了現有的代碼庫,其中包含許多類,其中實例屬性反映了存儲在數據庫中的值。我已經重構了許多這些屬性,以便推遲它們的數據庫查找。不會在構造函數中初始化,而只能在初讀時進行初始化。這些屬性不會在實例的整個生命周期內發生變化,但是它們是第一次計算的真正瓶頸,只有在特殊情況下才真正訪問。因此,它們也可以在從數據庫中檢索出來之后進行緩存(因此,它適合于記憶的定義,其中輸入只是“無輸入”)。我發現自己一遍又一遍地為各種類的各種屬性鍵入以下代碼片段:class testA(object):  def __init__(self):    self._a = None    self._b = None  @property  def a(self):    if self._a is None:      # Calculate the attribute now      self._a = 7    return self._a  @property  def b(self):    #etc我已經不知道有沒有使用Python的現有裝飾器來執行此操作?或者,是否有合理簡單的方法來定義裝飾器,從而做到這一點?我正在Python 2.5下工作,但是2.6答案如果有很大不同,可能仍然很有趣。注意在Python包含許多現成的裝飾器之前,就曾問過這個問題。我更新它只是為了更正術語。
查看完整描述

3 回答

?
婷婷同學_

TA貢獻1844條經驗 獲得超8個贊

對于各種強大的工具,我都使用bolton。


作為該庫的一部分,您具有cached屬性:


from boltons.cacheutils import cachedproperty


class Foo(object):

    def __init__(self):

        self.value = 4


    @cachedproperty

    def cached_prop(self):

        self.value += 1

        return self.value



f = Foo()

print(f.value)  # initial value

print(f.cached_prop)  # cached property is calculated

f.value = 1

print(f.cached_prop)  # same value for the cached property - it isn't calculated again

print(f.value)  # the backing value is different (it's essentially unrelated value)


查看完整回答
反對 回復 2019-10-24
?
鳳凰求蠱

TA貢獻1825條經驗 獲得超4個贊

這是惰性屬性裝飾器的示例實現:


import functools


def lazyprop(fn):

    attr_name = '_lazy_' + fn.__name__


    @property

    @functools.wraps(fn)

    def _lazyprop(self):

        if not hasattr(self, attr_name):

            setattr(self, attr_name, fn(self))

        return getattr(self, attr_name)


    return _lazyprop



class Test(object):


    @lazyprop

    def a(self):

        print 'generating "a"'

        return range(5)

互動環節:


>>> t = Test()

>>> t.__dict__

{}

>>> t.a

generating "a"

[0, 1, 2, 3, 4]

>>> t.__dict__

{'_lazy_a': [0, 1, 2, 3, 4]}

>>> t.a

[0, 1, 2, 3, 4]


查看完整回答
反對 回復 2019-10-24
?
慕工程0101907

TA貢獻1887條經驗 獲得超5個贊

我為自己編寫了此代碼...用于真正的一次性計算的惰性屬性。我喜歡它,因為它避免在對象上粘貼額外的屬性,并且一旦激活就不會浪費時間檢查屬性是否存在,等等:


import functools


class lazy_property(object):

    '''

    meant to be used for lazy evaluation of an object attribute.

    property should represent non-mutable data, as it replaces itself.

    '''


    def __init__(self, fget):

        self.fget = fget


        # copy the getter function's docstring and other attributes

        functools.update_wrapper(self, fget)


    def __get__(self, obj, cls):

        if obj is None:

            return self


        value = self.fget(obj)

        setattr(obj, self.fget.__name__, value)

        return value



class Test(object):


    @lazy_property

    def results(self):

        calcs = 1  # Do a lot of calculation here

        return calcs

注意:lazy_property該類是一個非數據描述符,這意味著它是只讀的。添加__set__方法會阻止其正常工作。


查看完整回答
反對 回復 2019-10-24
  • 3 回答
  • 0 關注
  • 444 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號