#12953: Bindable classes
-------------------------------------+--------------------------------------
Reporter: nthiery | Owner: jason
Type: enhancement | Status: positive_review
Priority: major | Milestone: sage-5.1
Component: misc | Resolution:
Keywords: days38 | Work issues:
Report Upstream: N/A | Reviewers: Franco Saliola
Authors: Nicolas M. ThiƩry | Merged in:
Dependencies: | Stopgaps:
-------------------------------------+--------------------------------------
Changes (by nthiery):
* keywords: => days38
* status: needs_review => positive_review
Old description:
> 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)
> }}}
New description:
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
--
Comment:
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!
--
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/12953#comment:2>
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 post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sage-trac?hl=en.