Abstract base class for Sage objects¶
- class sage.structure.sage_object.SageObject[source]¶
- 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_()[source]¶
- 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 - AsciiArtobject, see- sage.typeset.ascii_artfor 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 | / - >>> from sage.all import * >>> result = ascii_art(integral(exp(x+x**Integer(2))/(x+Integer(1)), x)) # needs sage.symbolic ... >>> result # needs sage.symbolic / | | 2 | x + x | e | ------- dx | x + 1 | / - Alternatively, you can use the - %display ascii_art/simplemagic 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() - >>> from sage.all import * >>> # needs sage.combinat >>> from sage.repl.interpreter import get_test_shell >>> shell = get_test_shell() >>> shell.run_cell('tab = StandardTableaux(3)[2]; tab') [[1, 2], [3]] >>> shell.run_cell('%display ascii_art') >>> shell.run_cell('tab') 1 2 3 >>> shell.run_cell('Tableaux.options(ascii_art="table", convention="French")') >>> shell.run_cell('tab') +---+ | 3 | +---+---+ | 1 | 2 | +---+---+ >>> shell.run_cell('%display plain') >>> shell.run_cell('Tableaux.options._reset()') >>> shell.quit() 
 - _cache_key()[source]¶
- 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 return- Truefor 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 - >>> from sage.all import * >>> # needs sage.rings.padics >>> K = Qq(Integer(9), names=('a',)); (a,) = K._first_ngens(1) >>> b = a + O(Integer(3)) >>> c = a + Integer(3) >>> b a + O(3) >>> c a + 3 + O(3^20) >>> b == c True >>> b == a True >>> 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) - >>> from sage.all import * >>> # needs sage.rings.padics >>> hash(b) Traceback (most recent call last): ... TypeError: unhashable type: 'sage.rings.padics.qadic_flint_CR.qAdicCappedRelativeElement' >>> @cached_method ... def f(x): return x==a >>> f(b) True >>> f(c) # if b and c were hashable, this would return True False >>> b._cache_key() (..., ((0, 1),), 0, 1) >>> c._cache_key() (..., ((0, 1), (1,)), 0, 20) - An implementation must make sure that for elements - aand- b, if- a != b, then also- a._cache_key() != b._cache_key(). In practice this means that the- _cache_keyshould 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 - >>> from sage.all import * >>> S = Qq(Integer(4), names=('a',)); (a,) = S._first_ngens(1)# needs sage.rings.padics >>> d = a + O(Integer(2)) # needs sage.rings.padics >>> b._cache_key() == d._cache_key() # this would be True if the parents were not included # needs sage.rings.padics False 
 - dumps(compress=True)[source]¶
- Dump - selfto a string- s, which can later be reconstituted as- selfusing- loads(s).- There is an optional boolean argument - compresswhich defaults to- True.- 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 - >>> from sage.all import * >>> from sage.misc.persist import comp >>> O = SageObject() >>> p_comp = O.dumps() >>> p_uncomp = O.dumps(compress=False) >>> comp.decompress(p_comp) == p_uncomp True >>> import pickletools >>> 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()[source]¶
- Return the custom name of this object, or - Noneif 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 - >>> from sage.all import * >>> P = QQ['x']; (x,) = P._first_ngens(1) >>> P.get_custom_name() is None True >>> P.rename('A polynomial ring') >>> P.get_custom_name() 'A polynomial ring' >>> P.reset_name() >>> P.get_custom_name() is None True 
 - parent()[source]¶
- Return the type of - selfto 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'> - >>> from sage.all import * >>> t = log(sqrt(Integer(2)) - Integer(1)) + log(sqrt(Integer(2)) + Integer(1)); t # needs sage.symbolic log(sqrt(2) + 1) + log(sqrt(2) - 1) >>> u = t.maxima_methods() # needs sage.symbolic >>> u.parent() # needs sage.symbolic <class 'sage.symbolic.maxima_wrapper.MaximaWrapper'> 
 - rename(x=None)[source]¶
- Change - selfso 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 - >>> from sage.all import * >>> x = PolynomialRing(QQ, 'x', sparse=True).gen() >>> g = x**Integer(3) + x - Integer(5) >>> g x^3 + x - 5 >>> g.rename('a polynomial') >>> g a polynomial >>> g + x x^3 + 2*x - 5 >>> h = g**Integer(100) >>> str(h)[:Integer(20)] 'x^300 + 100*x^298 - ' >>> h.rename('x^300 + ...') >>> h x^300 + ... >>> g.rename(None) >>> 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 - >>> from sage.all import * >>> a = RealNumber('3.14') >>> type(a) # needs sage.rings.real_mpfr <... 'sage.rings.real_mpfr.RealLiteral'> >>> 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_nameattribute.
 - reset_name()[source]¶
- 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 - >>> from sage.all import * >>> P = QQ['x']; (x,) = P._first_ngens(1) >>> P Univariate Polynomial Ring in x over Rational Field >>> P.rename('A polynomial ring') >>> P A polynomial ring >>> P.reset_name() >>> P Univariate Polynomial Ring in x over Rational Field 
 - save(filename=None, compress=True)[source]¶
- Save - selfto 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 - >>> from sage.all import * >>> # needs sage.symbolic >>> x = SR.var("x") >>> f = x**Integer(3) + Integer(5) >>> from tempfile import NamedTemporaryFile >>> with NamedTemporaryFile(suffix='.sobj') as t: ... f.save(t.name) ... load(t.name) x^3 + 5