Réécrivez l'extrait que j'ai écrit plus tôt. Une fois lu, la propriété sera conservée jusqu'à ce que l'objet soit détruit. C'est la spécification.
Vous pouvez également écrire pour utiliser un cache approprié en spécifiant un backend de trésorerie pour la variable décorateur. Faisons-le plus tard
dec.py
from functools import wraps
import mox
from unittest import TestCase
def cached_property(f):
prefix = '_cached_property_'
@wraps(f)
def _cached_property(self):
key = prefix + f.__name__
if hasattr(self, key):
return getattr(self, key)
value = f(self)
setattr(self, key, value)
return value
return property(_cached_property)
class TestCachedProperty(TestCase):
def setUp(self):
self.m = mox.Mox()
def tearDown(self):
self.m.UnsetStubs()
self.m = None
def test_call_1(self):
"""Simple call."""
# Procuder function that should be called twice.
producer = self.m.CreateMockAnything()
producer().AndReturn(30)
producer().AndReturn(101)
producer().AndReturn(None)
producer().AndReturn(0)
producer().AndReturn('')
class C(object):
@cached_property
def f(self):
return producer()
# Try
self.m.ReplayAll()
c = C()
c2 = C()
c3 = C()
c4 = C()
c5 = C()
# Verify
self.assertEqual(c.f, 30)
self.assertEqual(c.f, 30)
self.assertEqual(c._cached_property_f, 30)
self.assertEqual(c2.f, 101)
self.assertEqual(c2.f, 101)
self.assertEqual(c2._cached_property_f, 101)
self.assertEqual(c3.f, None)
self.assertEqual(c3.f, None)
self.assertEqual(c3._cached_property_f, None)
self.assertEqual(c4.f, 0)
self.assertEqual(c4.f, 0)
self.assertEqual(c4._cached_property_f, 0)
self.assertEqual(c5.f, '')
self.assertEqual(c5.f, '')
self.assertEqual(c5._cached_property_f, '')
self.m.VerifyAll()
return
def test_call_2(self):
"""Check that property function reference self."""
# Procuder function that should be called once.
producer = self.m.CreateMockAnything()
producer().AndReturn(30)
producer().AndReturn(101)
class C(object):
@cached_property
def f(self):
return self.g()
def g(self):
return producer()
# Try
self.m.ReplayAll()
c = C()
c2 = C()
# Verify
self.assertEqual(c.f, 30)
self.assertEqual(c.f, 30)
self.assertEqual(c._cached_property_f, 30)
self.assertEqual(c2.f, 101)
self.assertEqual(c2.f, 101)
self.assertEqual(c2._cached_property_f, 101)
self.m.VerifyAll()
return