Ticket #12953 (closed enhancement: fixed)
Bindable classes
| Reported by: | nthiery | Owned by: | jason |
|---|---|---|---|
| Priority: | major | Milestone: | sage-5.1 |
| Component: | misc | Keywords: | days38 |
| Cc: | sage-combinat | Work issues: | |
| Report Upstream: | N/A | Reviewers: | Franco Saliola |
| Authors: | Nicolas M. Thiéry | Merged in: | sage-5.1.beta1 |
| Dependencies: | Stopgaps: |
Description (last modified by nthiery) (diff)
From the documentation:
Bindable classes
This class implements a binding behavior for nested classes that
derive from it.
EXAMPLES:
Let us consider the following class ``Outer`` with a nested class ``Inner``::
sage: from sage.misc.nested_class import NestedClassMetaclass
sage: class Outer:
... __metaclass__ = NestedClassMetaclass # workaround for python pickling bug
... def f(self, *args):
... print self, args
...
... @staticmethod
... def f_static(*args):
... print args
...
... class Inner:
... def __init__(self, *args):
... print args
sage: obj = Outer()
By default, when Inner is a class nested in Outer, accessing
``obj.Inner`` returns the ``Inner`` class as is::
sage: obj.Inner is Outer.Inner
True
In particular, ``obj`` is completely ignored in the following call::
sage: x = obj.Inner(1,2,3)
(1, 2, 3)
This is similar to what happens with a staticmethod::
sage: obj.f_static(1,2,3)
(1, 2, 3)
In some cases, we would want instead Inner to receive ``obj`` as
parameter, like in a usual method call::
sage: obj.f(1,2,3)
<__main__.Outer object at ...> (1, 2, 3)
To this end, ``obj.f`` returns a *bound method*::
sage: obj.f
<bound method Outer.f of <__main__.Outer object at ...>>
so that ``obj.f(1,2,3)`` is equivalent to::
sage: Outer.f(obj, 1,2,3)
<__main__.Outer object at ...> (1, 2, 3)
``BindableClass`` gives this binding behavior to all its subclasses::
sage: from sage.misc.bindable_class import BindableClass
sage: class Outer:
... __metaclass__ = NestedClassMetaclass # workaround for python pickling bug
...
... class Inner(BindableClass):
... " some documentation "
... def __init__(self, obj, *args):
... print obj, args
Now, ``obj.Inner(1,2,3)`` is equivalent to Outer.Inner(obj, 1,2,3)::
sage: obj = Outer()
sage: x = obj.Inner(1,2,3)
<__main__.Outer object at ...> (1, 2, 3)
This feature will be extensively used for implementing SetsWithRealizations?; see e.g. #12959 and the upcoming NCSF #8899 patch
Attachments
Change History
comment:1 Changed 12 months ago by nthiery
- Status changed from new to needs_review
- Reviewers set to Franco Saliola
comment:2 Changed 12 months ago by nthiery
- Keywords days38 added
- Status changed from needs_review to positive_review
- Description modified (diff)
On behalf of Franco:
Comment: A variant would be to implement this feature using a class decorator. Practice will tell if we would need that variant. One advantage (or maybe sometimes an inconvenient?) of doing it by inheritance as implemented here is that all subclasses benefit from it, like, e.g., for UniqueRepresentation?.
Positive review!
Note: See
TracTickets for help on using
tickets.


For the record: all tests passed for me with 5.0.rc0 and the sage-combinat queue applied up to this patch.