### Navigation

- index
- modules |
- next |
- previous |
- Miscellaneous »

# Bindable classes

class `sage.misc.bindable_class.``BindableClass`

  Bases: `object`

  Bindable classes

  This class implements a binding behavior for nested classes that derive from it. Namely, if a nested class `Outer.Inner` derives from `BindableClass`, and if `outer` is an instance of `Outer`, then `outer.Inner(...)` is equivalent to `Outer.Inner(outer, ...)`.

  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 # just a workaround for Python misnaming nested classes
      ...
      ...       class Inner:
      ...           def __init__(self, *args):
      ...               print args
      ...
      ...       def f(self, *args):
      ...           print self, args
      ...
      ...       @staticmethod
      ...       def f_static(*args):
      ...           print args
      ...
      sage: outer = Outer()

  By default, when `Inner` is a class nested in `Outer`, accessing `outer.Inner` returns the `Inner` class as is:

      sage: outer.Inner is Outer.Inner
      True

  In particular, `outer` is completely ignored in the following call:

      sage: x = outer.Inner(1,2,3)
      (1, 2, 3)

  This is similar to what happens with a static method:

      sage: outer.f_static(1,2,3)
      (1, 2, 3)

  In some cases, we would want instead `Inner`` to receive `outer` as parameter, like in a usual method call:

      sage: outer.f(1,2,3)
      <__main__.Outer object at ...> (1, 2, 3)

  To this end, `outer.f` returns a bound method:

      sage: outer.f
      <bound method Outer.f of <__main__.Outer object at ...>>

  so that `outer.f(1,2,3)` is equivalent to:

      sage: Outer.f(outer, 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 # just a workaround for Python misnaming nested classes
      ...
      ...       class Inner(BindableClass):
      ...           " some documentation "
      ...           def __init__(self, outer, *args):
      ...               print outer, args

  Calling `Outer.Inner` returns the (unbound) class as usual:

      sage: Outer.Inner
      <class '__main__.Outer.Inner'>

  However, `outer.Inner(1,2,3)` is equivalent to `Outer.Inner(outer, 1,2,3)`:

      sage: outer = Outer()
      sage: x = outer.Inner(1,2,3)
      <__main__.Outer object at ...> (1, 2, 3)

  To achieve this, `outer.Inner` returns (some sort of) bound class:

      sage: outer.Inner
      <bound class '__main__.Outer.Inner' of <__main__.Outer object at ...>>

  Note

  This is not actually a class, but an instance of `functools.partial`:

      sage: type(outer.Inner).mro()
      [<class 'sage.misc.bindable_class.BoundClass'>,
       <type 'functools.partial'>,
       <type 'object'>]

  Still, documentation works as usual:

      sage: outer.Inner.__doc__
      ' some documentation '

  TESTS:

      sage: from sage.misc.bindable_class import Outer
      sage: TestSuite(Outer.Inner).run()
      sage: outer = Outer()
      sage: TestSuite(outer.Inner).run(skip=["_test_pickling"])

class `sage.misc.bindable_class.``BoundClass`(*args)

  Bases: `functools.partial`

class `sage.misc.bindable_class.``Inner2`

  Bases: `sage.misc.bindable_class.BindableClass`

  Some documentation for Inner2

class `sage.misc.bindable_class.``Outer`

  Bases: `object`

  A class with a bindable nested class, for testing purposes

  class `Inner`

    Bases: `sage.misc.bindable_class.BindableClass`

    Some documentation for Outer.Inner

  `Outer.``Inner2`

    alias of `Inner2`

### Navigation

- index
- modules |
- next |
- previous |
- Miscellaneous »