Fast methods via Cython¶
This module provides extension classes with useful methods of cython speed, that python classes can inherit.
Note
This module provides a cython base class WithEqualityById
implementing unique instance behaviour, and a cython base class
FastHashable_class, which has a quite fast hash
whose value can be freely chosen at initialisation time.
AUTHOR:
- Simon King (2013-02): Original version 
- Simon King (2013-10): Add - Singleton
- class sage.misc.fast_methods.FastHashable_class[source]¶
- Bases: - object- A class that has a fast hash method, returning a pre-assigned value. - Note - This is for internal use only. The class has a cdef attribute - _hash, that needs to be assigned (for example, by calling the init method, or by a direct assignment using cython). This is slower than using- provide_hash_by_id(), but has the advantage that the hash can be prescribed, by assigning a cdef attribute- _hash.
- class sage.misc.fast_methods.Singleton[source]¶
- Bases: - WithEqualityById- A base class for singletons. - A singleton is a class that allows to create not more than a single instance. This instance can also belong to a subclass, but it is not possible to have several subclasses of a singleton all having distinct unique instances. - In order to create a singleton, just add - Singletonto the list of base classes:- sage: from sage.misc.fast_methods import Singleton sage: class C(Singleton, SageObject): ....: def __init__(self): ....: print("creating singleton") sage: c = C() creating singleton sage: c2 = C() sage: c is c2 True - >>> from sage.all import * >>> from sage.misc.fast_methods import Singleton >>> class C(Singleton, SageObject): ... def __init__(self): ... print("creating singleton") >>> c = C() creating singleton >>> c2 = C() >>> c is c2 True - The unique instance of a singleton stays in memory as long as the singleton itself does. - Pickling, copying, hashing, and comparison are provided for by - Singletonaccording to the singleton paradigm. Note that pickling fails if the class is replaced by a sub-sub-class after creation of the instance:- sage: class D(C): ....: pass sage: import __main__ # This is only needed ... sage: __main__.C = C # ... in doctests sage: __main__.D = D # same here, only in doctests sage: orig = type(c) sage: c.__class__ = D sage: orig == type(c) False sage: loads(dumps(c)) Traceback (most recent call last): ... AssertionError: <class '__main__.D'> is not a direct subclass of <class 'sage.misc.fast_methods.Singleton'> - >>> from sage.all import * >>> class D(C): ... pass >>> import __main__ # This is only needed ... >>> __main__.C = C # ... in doctests >>> __main__.D = D # same here, only in doctests >>> orig = type(c) >>> c.__class__ = D >>> orig == type(c) False >>> loads(dumps(c)) Traceback (most recent call last): ... AssertionError: <class '__main__.D'> is not a direct subclass of <class 'sage.misc.fast_methods.Singleton'> 
- class sage.misc.fast_methods.WithEqualityById[source]¶
- Bases: - object- Provide hash and equality test based on identity. - Note - This class provides the unique representation behaviour of - UniqueRepresentation, together with- CachedRepresentation.- EXAMPLES: - Any instance of - UniqueRepresentationinherits from- WithEqualityById.- sage: class MyParent(Parent): ....: def __init__(self, x): ....: self.x = x ....: def __hash__(self): ....: return hash(self.x) sage: class MyUniqueParent(UniqueRepresentation, MyParent): pass sage: issubclass(MyUniqueParent, sage.misc.fast_methods.WithEqualityById) True - >>> from sage.all import * >>> class MyParent(Parent): ... def __init__(self, x): ... self.x = x ... def __hash__(self): ... return hash(self.x) >>> class MyUniqueParent(UniqueRepresentation, MyParent): pass >>> issubclass(MyUniqueParent, sage.misc.fast_methods.WithEqualityById) True - Inheriting from - WithEqualityByIdprovides unique representation behaviour:- sage: a = MyUniqueParent(1) sage: b = MyUniqueParent(2) sage: c = MyUniqueParent(1) sage: a is c True sage: d = MyUniqueParent(-1) sage: a == d False - >>> from sage.all import * >>> a = MyUniqueParent(Integer(1)) >>> b = MyUniqueParent(Integer(2)) >>> c = MyUniqueParent(Integer(1)) >>> a is c True >>> d = MyUniqueParent(-Integer(1)) >>> a == d False - The hash inherited from - MyParentis replaced by a hash that coincides with- object’s hash:- sage: hash(a) == hash(a.x) False sage: hash(a) == object.__hash__(a) True - >>> from sage.all import * >>> hash(a) == hash(a.x) False >>> hash(a) == object.__hash__(a) True - Warning - It is possible to inherit from - UniqueRepresentationand then overload equality test in a way that destroys the unique representation property. We strongly recommend against it! You should use- CachedRepresentationinstead.- sage: class MyNonUniqueParent(MyUniqueParent): ....: def __eq__(self, other): ....: return self.x^2 == other.x^2 sage: a = MyNonUniqueParent(1) sage: d = MyNonUniqueParent(-1) sage: a is MyNonUniqueParent(1) True sage: a == d True sage: a is d False - >>> from sage.all import * >>> class MyNonUniqueParent(MyUniqueParent): ... def __eq__(self, other): ... return self.x**Integer(2) == other.x**Integer(2) >>> a = MyNonUniqueParent(Integer(1)) >>> d = MyNonUniqueParent(-Integer(1)) >>> a is MyNonUniqueParent(Integer(1)) True >>> a == d True >>> a is d False