[PYTHON] [Überarbeiteter] Eigenschaftsdekorator, der Werte zwischenspeichert

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

Recommended Posts

[Überarbeiteter] Eigenschaftsdekorator, der Werte zwischenspeichert
Fassen Sie Pythons @property Decorator zusammen
Property Decorator verwenden?