Abstract base class for Sage objects#
- class sage.structure.sage_object.SageObject#
Bases:
object
Base class for all (user-visible) objects in Sage
Every object that can end up being returned to the user should inherit from
SageObject
.- _ascii_art_()#
Return an ASCII art representation.
To implement multi-line ASCII art output in a derived class you must override this method. Unlike
_repr_()
, which is sometimes used for the hash key, the output of_ascii_art_()
may depend on settings and is allowed to change during runtime.OUTPUT:
An
AsciiArt
object, seesage.typeset.ascii_art
for details.EXAMPLES:
You can use the
ascii_art()
function to get the ASCII art representation of any object in Sage:sage: result = ascii_art(integral(exp(x+x^2)/(x+1), x)) # needs sage.symbolic ... sage: result # needs sage.symbolic / | | 2 | x + x | e | ------- dx | x + 1 | /
Alternatively, you can use the
%display ascii_art/simple
magic to switch all output to ASCII art and back:sage: # needs sage.combinat sage: from sage.repl.interpreter import get_test_shell sage: shell = get_test_shell() sage: shell.run_cell('tab = StandardTableaux(3)[2]; tab') [[1, 2], [3]] sage: shell.run_cell('%display ascii_art') sage: shell.run_cell('tab') 1 2 3 sage: shell.run_cell('Tableaux.options(ascii_art="table", convention="French")') sage: shell.run_cell('tab') +---+ | 3 | +---+---+ | 1 | 2 | +---+---+ sage: shell.run_cell('%display plain') sage: shell.run_cell('Tableaux.options._reset()') sage: shell.quit()
- _cache_key()#
Return a hashable key which identifies this objects for caching. The output must be hashable itself, or a tuple of objects which are hashable or define a
_cache_key
.This method will only be called if the object itself is not hashable.
Some immutable objects (such as \(p\)-adic numbers) cannot implement a reasonable hash function because their
==
operator has been modified to returnTrue
for objects which might behave differently in some computations:sage: # needs sage.rings.padics sage: K.<a> = Qq(9) sage: b = a + O(3) sage: c = a + 3 sage: b a + O(3) sage: c a + 3 + O(3^20) sage: b == c True sage: b == a True sage: c == a False
If such objects defined a non-trivial hash function, this would break caching in many places. However, such objects should still be usable in caches. This can be achieved by defining an appropriate
_cache_key
:sage: # needs sage.rings.padics sage: hash(b) Traceback (most recent call last): ... TypeError: unhashable type: 'sage.rings.padics.qadic_flint_CR.qAdicCappedRelativeElement' sage: @cached_method ....: def f(x): return x==a sage: f(b) True sage: f(c) # if b and c were hashable, this would return True False sage: b._cache_key() (..., ((0, 1),), 0, 1) sage: c._cache_key() (..., ((0, 1), (1,)), 0, 20)
An implementation must make sure that for elements
a
andb
, ifa != b
, then alsoa._cache_key() != b._cache_key()
. In practice this means that the_cache_key
should always include the parent as its first argument:sage: S.<a> = Qq(4) # needs sage.rings.padics sage: d = a + O(2) # needs sage.rings.padics sage: b._cache_key() == d._cache_key() # this would be True if the parents were not included # needs sage.rings.padics False
- category()#
- dump(filename, compress=True)#
Same as self.save(filename, compress)
- dumps(compress=True)#
Dump
self
to a strings
, which can later be reconstituted asself
usingloads(s)
.There is an optional boolean argument
compress
which defaults toTrue
.EXAMPLES:
sage: from sage.misc.persist import comp sage: O = SageObject() sage: p_comp = O.dumps() sage: p_uncomp = O.dumps(compress=False) sage: comp.decompress(p_comp) == p_uncomp True sage: import pickletools sage: pickletools.dis(p_uncomp) 0: \x80 PROTO 2 2: c GLOBAL 'sage.structure.sage_object SageObject' 41: q BINPUT ... 43: ) EMPTY_TUPLE 44: \x81 NEWOBJ 45: q BINPUT ... 47: . STOP highest protocol among opcodes = 2
- get_custom_name()#
Return the custom name of this object, or
None
if it is not renamed.EXAMPLES:
sage: P.<x> = QQ[] sage: P.get_custom_name() is None True sage: P.rename('A polynomial ring') sage: P.get_custom_name() 'A polynomial ring' sage: P.reset_name() sage: P.get_custom_name() is None True
- parent()#
Return the type of
self
to support the coercion framework.EXAMPLES:
sage: t = log(sqrt(2) - 1) + log(sqrt(2) + 1); t # needs sage.symbolic log(sqrt(2) + 1) + log(sqrt(2) - 1) sage: u = t.maxima_methods() # needs sage.symbolic sage: u.parent() # needs sage.symbolic <class 'sage.symbolic.maxima_wrapper.MaximaWrapper'>
- rename(x=None)#
Change self so it prints as x, where x is a string.
If x is
None
, the existing custom name is removed.Note
This is only supported for Python classes that derive from SageObject.
EXAMPLES:
sage: x = PolynomialRing(QQ, 'x', sparse=True).gen() sage: g = x^3 + x - 5 sage: g x^3 + x - 5 sage: g.rename('a polynomial') sage: g a polynomial sage: g + x x^3 + 2*x - 5 sage: h = g^100 sage: str(h)[:20] 'x^300 + 100*x^298 - ' sage: h.rename('x^300 + ...') sage: h x^300 + ... sage: g.rename(None) sage: g x^3 + x - 5
Real numbers are not Python classes, so rename is not supported:
sage: a = 3.14 sage: type(a) # needs sage.rings.real_mpfr <... 'sage.rings.real_mpfr.RealLiteral'> sage: a.rename('pi') # needs sage.rings.real_mpfr Traceback (most recent call last): ... NotImplementedError: object does not support renaming: 3.14000000000000
Note
The reason C-extension types are not supported by default is if they were then every single one would have to carry around an extra attribute, which would be slower and waste a lot of memory.
To support them for a specific class, add a
cdef public _SageObject__custom_name
attribute.
- reset_name()#
Remove the custom name of an object.
EXAMPLES:
sage: P.<x> = QQ[] sage: P Univariate Polynomial Ring in x over Rational Field sage: P.rename('A polynomial ring') sage: P A polynomial ring sage: P.reset_name() sage: P Univariate Polynomial Ring in x over Rational Field
- save(filename=None, compress=True)#
Save self to the given filename.
EXAMPLES:
sage: # needs sage.symbolic sage: x = SR.var("x") sage: f = x^3 + 5 sage: from tempfile import NamedTemporaryFile sage: with NamedTemporaryFile(suffix=".sobj") as t: ....: f.save(t.name) ....: load(t.name) x^3 + 5