28. globalformat
— Set global ouput format for built-in types.¶
One of the major shortcomings of Python is the lack of global print options allowing to set the output format for built-in type globally for your application. Especially the default formatting of float values is annoyingly large.
>>> sqrt2 = 2 ** 0.5
>>> print(sqrt2)
1.4142135623730951
To get a shorter output with less decimals one can round the value, or use a format specifier:
>>> print(round(sqrt2, 4))
1.4142
>>> print(f"{sqrt2:.4f}")
1.4142
But this is only convenient when you have to output a single float, but doesn’t work for floats embedded in a container.
>>> cont = (1/2, 1/3, 1/16)
>>> print(cont)
(0.5, 0.3333333333333333, 0.0625)
Luckily, for most numerical work we can (and should) use NumPy, which allows to set global print options for its classes:
>>> import numpy as np
>>> np.set_printoptions(precision=4, floatmode='fixed')
>>> ar = np.array(cont)
>>> print(ar)
[0.5000 0.3333 0.0625]
But even then one falls back to the Python default for a single array element:
>>> print(ar[0], ar[1])
0.5 0.3333333333333333
The solution would be to override float.__repr__, but Python won’t let you:
>>> float.__repr__ = lambda f: f"{f:.4f}"
Traceback (most recent call last):
...
TypeError: cannot set '__repr__' attribute of immutable type 'float'
But since this is Python, there must be some way to overcome this hurdle. And I finally found one: the forbiddenfruit module (https://pypi.org/project/forbiddenfruit/) by Lincoln de Sousa <lincoln@clarete.li> allows to do all kinds of monkeypatching on builtin types. Since we only need a small part of it, we copied the relevant things in this module, thus avoiding that our users need to install that module. Now we can set our own float.__repr__ method, which can take account of a global precision setting.
>>> setfloatformat('.4f') # set fixed format for all floats
>>> print(cont)
(0.5000, 0.3333, 0.0625)
>>> setfloatformat('') # reset Python's default
>>> print(cont)
(0.5, 0.3333333333333333, 0.0625)
Or you can use the floatformat context manager to temporarily change the format:
>>> with floatformat('.4f'):
... print('.4f', cont)
... with floatformat('10.2e'):
... print('10.2e', cont)
... print('back to .4f', cont)
.4f (0.5000, 0.3333, 0.0625)
10.2e ( 5.00e-01, 3.33e-01, 6.25e-02)
back to .4f (0.5000, 0.3333, 0.0625)
>>> print('back to default', cont)
back to default (0.5, 0.3333333333333333, 0.0625)
28.1. Classes defined in module globalformat¶
- class globalformat.floatformat(fmt)[source]¶
Context manager to temporarily change the global float format.
- Parameters:
fmt (str) – A format string like in
setfloatformat()
.
Notes
On exit, the global float format is reset to what is was before entering.
28.2. Functions defined in module globalformat¶
- globalformat.setfloatformat(fmt)[source]¶
Set global default format for float
- Parameters:
fmt (str) – A format string to format a single float number. For example: ‘.4f’ will format the float with 4 decimals. An empty string resets the format to Python’s default. An invalid format string raises an Exception.