This file is indexed.

/usr/share/doc/python-traits/examples/tutorials/traits_4.0/decorators/cached_property.py is in python-traits 4.1.0-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#  Copyright (c) 2007, Enthought, Inc.
#  License: BSD Style.

#--(cached_property Decorator)--------------------------------------------------
"""
cached_property Decorator
=========================

New in Traits 3.0 is the *cached_property* method decorator which helps
streamline the process of writing properties which cache their current value.

Defining properties is a very powerful technique for exposing as traits items
whose value depends upon the current state of other object traits. In
particular, this can be very useful for creating synthetic traits which are
editable or displayable in a traits-based user interface.

In some cases however, the cost of computing the current value of a property
may be fairly expensive, so it is often a good idea to *cache* the most recently
computed value of the property, and return it as the value of the property until
one of the traits the property depends upon changes value, at which point the
cache should be cleared and the property value recomputed the next time its
value is requested.

Combined with the **Property** *depends_on* metadata, the *cached_property*
decorator greatly simplifies the process of writing a cached property. Take a
look at the following code for example::

    class TestScores ( HasPrivateTraits ):

        scores  = List( Int )
        average = Property( depends_on = 'scores' )

        @cached_property
        def _get_average ( self ):
            s = self.scores
            return (float( reduce( lambda n1, n2: n1 + n2, s, 0 ) ) / len( s ))

Presumably this is much easier to write and understand that the following
equivalent code written without using *depends_on* and *cached_property*::

    class TestScores ( HasPrivateTraits ):

        scores  = List( Int )
        average = Property

        def _get_average ( self ):
            if self._average is None:
                s = self.scores
                self._average = (float( reduce( lambda n1, n2: n1 + n2, s, 0 ) )
                                 / len( s ))
            return self._average

        def _scores_changed ( self ):
            old, self._average = self._average, None
            self.trait_property_changed( 'average', old, self._average )

        def _scores_items_changed ( self ):
            self._scores_changed()

The *cached_property* decorator takes no arguments, and should simply be
written on the line preceding the property's *getter* method, as shown in the
previous example.

Use of the *cached_property* decorator also eliminates the need to add
*cached = True* metadata to the property declaration, as was previously required
when using *depends_on* metadata with a cached property definition.
"""
#--<Imports>--------------------------------------------------------------------

from traits.api import *
from traitsui.api import *

#--[TestScores Class]-----------------------------------------------------------

class TestScores ( HasPrivateTraits ):

    scores  = List( Int )
    average = Property( depends_on = 'scores' )

    @cached_property
    def _get_average ( self ):
        print "...computing average:",
        s = self.scores
        return (float( reduce( lambda n1, n2: n1 + n2, s, 0 ) ) / len( s ))

#--[Example*]-------------------------------------------------------------------

# Create a sample TestScores object with some sample scores:
test_scores = TestScores( scores = [ 89, 93, 76, 84, 62, 96, 75, 81, 69, 90 ] )

# Display the average:
print 'First average:', test_scores.average
print 'Check that again:', test_scores.average

# Now add a few more late scores into the mix:
test_scores.scores.extend( [ 85, 61, 70 ] )

# And display the new average:
print 'Second average:', test_scores.average