Easy caching

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • jalanb3

    Easy caching

    Evening all,

    And thank you for your valuable reading skills.

    The following pattern turned up in coding tonight.
    It works, but I'm suspicious, it just seems too easy.

    So any comments or constructive criticisms welcome ?

    *** Start doctest format ***
    >>class Cacher:
    ... def __init__(self):
    ... self.value_in_d atabase = 0
    ...
    ... def very_slow_datab ase_access(self ):
    ... return self.value_in_d atabase
    ...
    ... @property
    ... def show(self):
    ... result = self.very_slow_ database_access ()
    ... self.show = result
    ... return result
    ...
    >>>
    Create an instance
    >>cacher = Cacher()
    Someone writes to the database
    >>cacher.value_ in_database = 9
    Call show as a method, get the value
    >>print cacher.show
    9

    show is now a cached string
    >>print cacher.show
    9

    show is not a method so
    if someone else writes to the database
    we will not see the change
    >>cacher.value_ in_database = 7
    >>print cacher.show
    9

    To force another read from the database
    delete the string attribute
    >>del cacher.show
    Next time we try to use the attribute
    Python will find the method again
    >>print cacher.show
    7

    ***

    --
    Alan



  • Peter Otten

    #2
    Re: Easy caching

    jalanb3 wrote:
    Evening all,
    >
    And thank you for your valuable reading skills.
    >
    The following pattern turned up in coding tonight.
    It works, but I'm suspicious, it just seems too easy.
    >
    So any comments or constructive criticisms welcome ?
    >
    *** Start doctest format ***
    >
    >class Cacher:
    ... def __init__(self):
    ... self.value_in_d atabase = 0
    ...
    ... def very_slow_datab ase_access(self ):
    ... return self.value_in_d atabase
    ...
    ... @property
    ... def show(self):
    ... result = self.very_slow_ database_access ()
    ... self.show = result
    ... return result
    ...
    The above only works because properties don't work with classic class. If
    you make Cacher a newstyle class (have it inherit from object) you'll get
    an AttributeError. Therefore I think it would be cleaner to either

    use __getattr__() or

    change the Cacher to something like

    class Cacher(object):
    def __init__(self):
    self._show = None
    # ...

    @property
    def show(self):
    result = self._show
    if result is None:
    result = self._show = self.very_slow_ database_access ()
    return result

    Peter

    Comment

    • M.-A. Lemburg

      #3
      Re: Easy caching

      On 2008-11-13 09:03, Peter Otten wrote:
      jalanb3 wrote:
      >
      >Evening all,
      >>
      >And thank you for your valuable reading skills.
      >>
      >The following pattern turned up in coding tonight.
      >It works, but I'm suspicious, it just seems too easy.
      >>
      >So any comments or constructive criticisms welcome ?
      >>
      >*** Start doctest format ***
      >>
      >>>>class Cacher:
      >... def __init__(self):
      >... self.value_in_d atabase = 0
      >...
      >... def very_slow_datab ase_access(self ):
      >... return self.value_in_d atabase
      >...
      >... @property
      >... def show(self):
      >... result = self.very_slow_ database_access ()
      >... self.show = result
      >... return result
      >...
      >
      The above only works because properties don't work with classic class. If
      you make Cacher a newstyle class (have it inherit from object) you'll get
      an AttributeError. Therefore I think it would be cleaner to either
      >
      use __getattr__() or
      >
      change the Cacher to something like
      >
      class Cacher(object):
      def __init__(self):
      self._show = None
      # ...
      >
      @property
      def show(self):
      result = self._show
      if result is None:
      result = self._show = self.very_slow_ database_access ()
      return result
      You should also consider not using a property for this at all.

      Attribute access is supposed to be fast and, if at all, only cause
      AttributeErrors .

      Your self.very_slow_ database_access () call can raise all sorts of
      errors and likely take much too long for what a casual user would
      expect from writing print (cache.show).

      It's much better to write this as method which then uses an
      instance attribute for caching the value read from the database.

      --
      Marc-Andre Lemburg
      eGenix.com

      Professional Python Services directly from the Source (#1, Nov 13 2008)
      >>Python/Zope Consulting and Support ... http://www.egenix.com/
      >>mxODBC.Zope.D atabase.Adapter ... http://zope.egenix.com/
      >>mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
      _______________ _______________ _______________ _______________ ____________

      :::: Try mxODBC.Zope.DA for Windows,Linux,S olaris,MacOSX for free ! ::::


      eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48
      D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
      Registered at Amtsgericht Duesseldorf: HRB 46611

      Comment

      Working...