Python备注/延迟查找属性装饰器 [英] Python memoising/deferred lookup property decorator

查看:88
本文介绍了Python备注/延迟查找属性装饰器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,我浏览了现有的代码库,其中包含许多类,其中实例属性反映了存储在数据库中的值。我重构了许多这些属性,以便推迟它们的数据库查找。不会在构造函数中初始化,而只能在初读时进行初始化。这些属性不会在实例的整个生命周期内发生变化,但它们是第一次计算的真正瓶颈,只有在特殊情况下才真正访问。因此,它们也可以在从数据库中检索后进行缓存(因此符合 memoisation 的定义,其中输入只是无输入。)。

Recently I've gone through an existing code base containing many classes where instance attributes reflect values stored in a database. I've refactored a lot of these attributes to have their database lookups be deferred, ie. not be initialised in the constructor but only upon first read. These attributes do not change over the lifetime of the instance, but they're a real bottleneck to calculate that first time and only really accessed for special cases. Hence they can also be cached after they've been retrieved from the database (this therefore fits the definition of memoisation where the input is simply "no input").

我发现自己为各种类中的各种属性重复输入以下代码段:

I find myself typing the following snippet of code over and over again for various attributes across various classes:

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的现有装饰器来执行此操作?或者,是否有一种相当简单的方法来定义执行此操作的装饰器?

Is there an existing decorator to do this already in Python that I'm simply unaware of? Or, is there a reasonably simple way to define a decorator that does this?

我正在使用Python 2.5,但是2.6答案可能仍然很有趣,如果它们确实很重要

I'm working under Python 2.5, but 2.6 answers might still be interesting if they are significantly different.

这个问题是在Python包含许多现成的装饰器之前被问到的。我只是为了纠正术语而更新了它。

This question was asked before Python included a lot of ready-made decorators for this. I have updated it only to correct terminology.

推荐答案

对于各种出色的实用程序,我正在使用 boltons

For all sorts of great utilities I'm using boltons.

作为该库的一部分,您具有 cachedproperty

As part of that library you have cachedproperty:

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)

这篇关于Python备注/延迟查找属性装饰器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆