Loading django/utils/functional.py +6 −2 Original line number Diff line number Diff line Loading @@ -45,14 +45,18 @@ class cached_property(object): """ Decorator that converts a method with a single self argument into a property cached on the instance. Optional ``name`` argument allows you to make cached properties of other methods. (e.g. url = cached_property(get_absolute_url, name='url') ) """ def __init__(self, func): def __init__(self, func, name=None): self.func = func self.name = name or func.__name__ def __get__(self, instance, type=None): if instance is None: return self res = instance.__dict__[self.func.__name__] = self.func(instance) res = instance.__dict__[self.name] = self.func(instance) return res Loading docs/ref/utils.txt +19 −1 Original line number Diff line number Diff line Loading @@ -423,7 +423,7 @@ Atom1Feed .. module:: django.utils.functional :synopsis: Functional programming tools. .. class:: cached_property(object) .. class:: cached_property(object, name) The ``@cached_property`` decorator caches the result of a method with a single ``self`` argument as a property. The cached result will persist Loading Loading @@ -483,6 +483,24 @@ Atom1Feed database by some other process in the brief interval between subsequent invocations of a method on the same instance. .. versionadded:: 1.8 You can use the ``name`` argument to make cached properties of other methods. For example, if you had an expensive ``get_friends()`` method and wanted to allow calling it without retrieving the cached value, you could write:: friends = cached_property(get_friends, name='friends') While ``person.get_friends()`` will recompute the friends on each call, the value of the cached property will persist until you delete it as described above:: x = person.friends # calls first time y = person.get_friends() # calls again z = person.friends # does not call x is z # is True .. function:: allow_lazy(func, *resultclasses) Django offers many utility functions (particularly in ``django.utils``) Loading tests/utils_tests/test_functional.py +9 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,11 @@ class FunctionalTestCase(unittest.TestCase): def value(self): return 1, object() def other_value(self): return 1 other = cached_property(other_value, name='other') a = A() # check that it is cached Loading @@ -67,6 +72,10 @@ class FunctionalTestCase(unittest.TestCase): # check that it behaves like a property when there's no instance self.assertIsInstance(A.value, cached_property) # check that overriding name works self.assertEqual(a.other, 1) self.assertTrue(callable(a.other_value)) def test_lazy_equality(self): """ Tests that == and != work correctly for Promises. Loading Loading
django/utils/functional.py +6 −2 Original line number Diff line number Diff line Loading @@ -45,14 +45,18 @@ class cached_property(object): """ Decorator that converts a method with a single self argument into a property cached on the instance. Optional ``name`` argument allows you to make cached properties of other methods. (e.g. url = cached_property(get_absolute_url, name='url') ) """ def __init__(self, func): def __init__(self, func, name=None): self.func = func self.name = name or func.__name__ def __get__(self, instance, type=None): if instance is None: return self res = instance.__dict__[self.func.__name__] = self.func(instance) res = instance.__dict__[self.name] = self.func(instance) return res Loading
docs/ref/utils.txt +19 −1 Original line number Diff line number Diff line Loading @@ -423,7 +423,7 @@ Atom1Feed .. module:: django.utils.functional :synopsis: Functional programming tools. .. class:: cached_property(object) .. class:: cached_property(object, name) The ``@cached_property`` decorator caches the result of a method with a single ``self`` argument as a property. The cached result will persist Loading Loading @@ -483,6 +483,24 @@ Atom1Feed database by some other process in the brief interval between subsequent invocations of a method on the same instance. .. versionadded:: 1.8 You can use the ``name`` argument to make cached properties of other methods. For example, if you had an expensive ``get_friends()`` method and wanted to allow calling it without retrieving the cached value, you could write:: friends = cached_property(get_friends, name='friends') While ``person.get_friends()`` will recompute the friends on each call, the value of the cached property will persist until you delete it as described above:: x = person.friends # calls first time y = person.get_friends() # calls again z = person.friends # does not call x is z # is True .. function:: allow_lazy(func, *resultclasses) Django offers many utility functions (particularly in ``django.utils``) Loading
tests/utils_tests/test_functional.py +9 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,11 @@ class FunctionalTestCase(unittest.TestCase): def value(self): return 1, object() def other_value(self): return 1 other = cached_property(other_value, name='other') a = A() # check that it is cached Loading @@ -67,6 +72,10 @@ class FunctionalTestCase(unittest.TestCase): # check that it behaves like a property when there's no instance self.assertIsInstance(A.value, cached_property) # check that overriding name works self.assertEqual(a.other, 1) self.assertTrue(callable(a.other_value)) def test_lazy_equality(self): """ Tests that == and != work correctly for Promises. Loading