#12978: conditionally_defined decorator for methods and other attributes
-------------------------------------------------+-------------------------
       Reporter:  nthiery                        |        Owner:  jason
           Type:  enhancement                    |       Status:  new
       Priority:  major                          |    Milestone:  sage-
      Component:  misc                           |  wishlist
       Keywords:  categories,                    |   Resolution:
  conditionally_defined                          |    Merged in:
        Authors:                                 |    Reviewers:
Report Upstream:  N/A                            |  Work issues:
         Branch:                                 |       Commit:
   Dependencies:  #15056                         |     Stopgaps:
-------------------------------------------------+-------------------------

Comment (by SimonKing):

 By the way, here is yet another example. This time, it is for a special
 Python method (`__len__`).

 Scenario: We have a class A, with `len` being implemented. But the
 instances are mutable. in a sub-class B, some instances are immutable (but
 not all). If an instance is immutable, we want that the length is cached
 (which is possible by #12601).

 This can be done as follows:
 {{{
 sage: class A(object):
 ....:     def __init__(self, n):
 ....:         self.data = range(n)
 ....:     def __len__(self):
 ....:         return len(self.data)
 sage: class B(A):
 ....:     def __init__(self, n, immutable):
 ....:         A.__init__(self, n)
 ....:         if immutable:
 ....:             self.is_immutable = True
 ....:     @conditionally_defined("is_immutable")
 ....:     @cached_method
 ....:     def __len__(self):
 ....:         return super(B,self).__len__()
 }}}
 First of all, the length works for both mutable and "immutable" instances
 of B:
 {{{
 sage: a = B(3,False)
 sage: b = B(5,True)
 sage: len(a)
 3
 sage: len(b)
 5
 }}}
 Of course, one can alter both instances, but we see that the length of b
 is cached, in contrast to the length of a:
 {{{
 sage: a.data.append(4)
 sage: b.data.append(5)
 sage: len(a)
 4
 sage: len(b)
 5
 sage: len(b.data)
 6
 }}}

 Note that the cached length function is very fast. Compare with this:
 {{{
 sage: class C(object):
 ....:     def __len__(self):
 ....:         return int(5)
 ....:
 sage: c = C()
 sage: len(c)
 5
 sage: len(b)
 5
 sage: %timeit len(c)
 1000000 loops, best of 3: 793 ns per loop
 sage: %timeit len(b)
 1000000 loops, best of 3: 377 ns per loop
 }}}

 This is because a `CachedMethodCallerNoArgs` has Cython speed.

--
Ticket URL: <http://trac.sagemath.org/ticket/12978#comment:23>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica, 
and MATLAB

-- 
You received this message because you are subscribed to the Google Groups 
"sage-trac" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sage-trac.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to