Created
March 28, 2015 06:48
-
-
Save mzipay/ea4f89e522d8e91df584 to your computer and use it in GitHub Desktop.
Python lazy non-data descriptor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
# Copyright (c) 2015 Matthew Zipay <mattz@ninthtest.net>. All rights reserved. | |
# Licensed under the MIT License <http://opensource.org/licenses/MIT>. | |
class lazy: | |
r"""Decorate a no-arg getter to have lazy initialization behavior. | |
The first time the property is accessed on an instance, the computed | |
value is stored in the instance ``__dict__`` (using the same name as | |
the getter). Subsequent access returns the already-computed value as | |
a simple instance attribute. | |
This works because an attribute in an instance ``__dict__`` takes | |
precendence over a same-named, non-data descriptor in a class | |
``__dict__``. | |
>>> class Example: | |
... @lazy | |
... def expensive(self): | |
... print("initializing...") | |
... return "the computed value" | |
... | |
>>> x = Example() | |
>>> x.expensive | |
initializing... | |
'the computed value' | |
>>> x.expensive | |
'the computed value' | |
""" | |
def __init__(self, fget): | |
""" | |
:param fget: a no-arg method that computes and returns a value | |
""" | |
self._fget = fget | |
def __get__(self, obj, obj_type=None): | |
"""Return the computed value after setting it as an instance | |
attribute with the same name as the descriptor. | |
:param obj: an instance of the class that owns the getter | |
:keyword obj_type: the class of *obj* | |
:return: the value computed and returned by the getter | |
""" | |
if (obj is not None): | |
value = self._fget(obj) | |
setattr(obj, self._fget.__name__, value) | |
return value | |
# just return the descriptor itself if there's no instance | |
return self |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment