Schreiben Sie das zuvor geschriebene Snippet neu. Nach dem Lesen bleibt die Eigenschaft erhalten, bis das Objekt zerstört wird. Dies ist die Spezifikation.
Sie können auch schreiben, um einen geeigneten Cache zu verwenden, indem Sie ein Cash-Backend für die Decorator-Variable angeben. Lass es uns später tun
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