Bindable classes¶
- class sage.misc.bindable_class.BindableClass[source]¶
- Bases: - object- Bindable classes. - This class implements a binding behavior for nested classes that derive from it. Namely, if a nested class - Outer.Innerderives from- BindableClass, and if- outeris an instance of- Outer, then- outer.Inner(...)is equivalent to- Outer.Inner(outer, ...).- EXAMPLES: - Let us consider the following class - Outerwith a nested class- Inner:- sage: from sage.misc.nested_class import NestedClassMetaclass sage: class Outer(metaclass=NestedClassMetaclass): ....: class Inner: ....: def __init__(self, *args): ....: print(args) ....: def f(self, *args): ....: print("{} {}".format(self, args)) ....: @staticmethod ....: def f_static(*args): ....: print(args) sage: outer = Outer() - >>> from sage.all import * >>> from sage.misc.nested_class import NestedClassMetaclass >>> class Outer(metaclass=NestedClassMetaclass): ... class Inner: ... def __init__(self, *args): ... print(args) ... def f(self, *args): ... print("{} {}".format(self, args)) ... @staticmethod ... def f_static(*args): ... print(args) >>> outer = Outer() - By default, when - Inneris a class nested in- Outer, accessing- outer.Innerreturns the- Innerclass as is:- sage: outer.Inner is Outer.Inner True - >>> from sage.all import * >>> outer.Inner is Outer.Inner True - In particular, - outeris completely ignored in the following call:- sage: x = outer.Inner(1,2,3) (1, 2, 3) - >>> from sage.all import * >>> x = outer.Inner(Integer(1),Integer(2),Integer(3)) (1, 2, 3) - This is similar to what happens with a static method: - sage: outer.f_static(1,2,3) (1, 2, 3) - >>> from sage.all import * >>> outer.f_static(Integer(1),Integer(2),Integer(3)) (1, 2, 3) - In some cases, we would want instead - Innerto receive- outeras parameter, like in a usual method call:- sage: outer.f(1,2,3) <__main__.Outer object at ...> (1, 2, 3) - >>> from sage.all import * >>> outer.f(Integer(1),Integer(2),Integer(3)) <__main__.Outer object at ...> (1, 2, 3) - To this end, - outer.freturns a bound method:- sage: outer.f <bound method Outer.f of <__main__.Outer object at ...>> - >>> from sage.all import * >>> 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) - >>> from sage.all import * >>> Outer.f(outer, Integer(1),Integer(2),Integer(3)) <__main__.Outer object at ...> (1, 2, 3) - BindableClassgives this binding behavior to all its subclasses:- sage: from sage.misc.bindable_class import BindableClass sage: class Outer(metaclass=NestedClassMetaclass): ....: class Inner(BindableClass): ....: " some documentation " ....: def __init__(self, outer, *args): ....: print("{} {}".format(outer, args)) - >>> from sage.all import * >>> from sage.misc.bindable_class import BindableClass >>> class Outer(metaclass=NestedClassMetaclass): ... class Inner(BindableClass): ... " some documentation " ... def __init__(self, outer, *args): ... print("{} {}".format(outer, args)) - Calling - Outer.Innerreturns the (unbound) class as usual:- sage: Outer.Inner <class '__main__.Outer.Inner'> - >>> from sage.all import * >>> 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) - >>> from sage.all import * >>> outer = Outer() >>> x = outer.Inner(Integer(1),Integer(2),Integer(3)) <__main__.Outer object at ...> (1, 2, 3) - To achieve this, - outer.Innerreturns (some sort of) bound class:- sage: outer.Inner <bound class '__main__.Outer.Inner' of <__main__.Outer object at ...>> - >>> from sage.all import * >>> 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'>, <... 'functools.partial'>, <... 'object'>] - >>> from sage.all import * >>> type(outer.Inner).mro() [<class 'sage.misc.bindable_class.BoundClass'>, <... 'functools.partial'>, <... 'object'>] - Still, documentation works as usual: - sage: outer.Inner.__doc__ '...some documentation ' - >>> from sage.all import * >>> outer.Inner.__doc__ '...some documentation ' 
- class sage.misc.bindable_class.Inner2[source]¶
- Bases: - BindableClass- Some documentation for Inner2