Skip to content

Bindable classes #12953

@nthiery

Description

@nthiery

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

CC: @sagetrac-sage-combinat

Component: misc

Keywords: days38

Author: Nicolas M. Thiéry

Reviewer: Franco Saliola

Merged: sage-5.1.beta1

Issue created by migration from https://trac.sagemath.org/ticket/12953

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions