Lazy strings

Based on speaklater:

A lazy string is an object that behaves almost exactly like a string but where the value is not computed until needed. To define a lazy string you specify a function that produces a string together with the appropriate arguments for that function. Sage uses lazy strings in sage.misc.misc so that the filenames for SAGE_TMP (which depends on the pid of the process running Sage) are not computed when importing the Sage library. This means that when the doctesting code imports the Sage library and then forks, the variable SAGE_TMP depends on the new pid rather than the old one.


sage: from sage.misc.lazy_string import lazy_string
sage: L = []
sage: s = lazy_string(lambda x: str(len(x)), L)
sage: L.append(5)
sage: s

Note that the function is recomputed each time:

sage: L.append(6)
sage: s

Checks if the given object is a lazy string.


sage: from sage.misc.lazy_string import lazy_string, is_lazy_string
sage: f = lambda: "laziness"
sage: s = lazy_string(f)
sage: is_lazy_string(s)
sage.misc.lazy_string.lazy_string(f, *args, **kwargs)

Creates a lazy string.


  • f, either a callable or a (format) string

  • positional arguments that are given to f, either by calling or by applying it as a format string

  • named arguments, that are forwarded to f if it is not a string


sage: from sage.misc.lazy_string import lazy_string
sage: f = lambda x: "laziness in "+str(x)
sage: s = lazy_string(f, ZZ); s
l'laziness in Integer Ring'

Here, we demonstrate that the evaluation is postponed until the value is needed, and that the result is not cached:

sage: class C:
....:     def __repr__(self):
....:         print("determining string representation")
....:         return "a test"
sage: c = C()
sage: s = lazy_string("this is %s", c)
sage: s
determining string representation
l'this is a test'
sage: s == 'this is a test'
determining string representation
sage: unicode(s)  # py2
determining string representation
u'this is a test'