1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
.. currentmodule:: pint
String formatting specification
===============================
The conversion of :py:class:`Unit`, :py:class:`Quantity` and :py:class:`Measurement`
objects to strings (e.g. through the :py:class:`str` builtin or f-strings) can be
customized using :ref:`format specifications <formatspec>`. The basic format is:
.. code-block:: none
[magnitude format][modifier][pint format]
where each part is optional and the order of these is arbitrary.
.. doctest::
>>> import pint
>>> ureg = pint.UnitRegistry()
>>> q = 2.3e-6 * ureg.m ** 3 / (ureg.s ** 2 * ureg.kg)
>>> f"{q:~P}" # short pretty
'2.3×10⁻⁶ m³/kg/s²'
>>> f"{q:~#P}" # compact short pretty
'2.3 mm³/g/s²'
>>> f"{q:P#~}" # also compact short pretty
'2.3 mm³/g/s²'
>>> f"{q:.2f~#P}" # short compact pretty with 2 float digits
'2.30 mm³/g/s²'
>>> f"{q:#~}" # short compact default
'2.3 mm ** 3 / g / s ** 2'
In case the format is omitted, the corresponding value in the formatter
``.default_format`` attribute is filled in. For example:
.. doctest::
>>> ureg.formatter.default_format = "P"
>>> f"{q}"
'2.3×10⁻⁶ meter³/kilogram/second²'
Pint Format Types
-----------------
``pint`` comes with a variety of unit formats. These impact the complete representation:
======= =============== ======================================================================
Spec Name Examples
======= =============== ======================================================================
``D`` default ``3.4e+09 kilogram * meter / second ** 2``
``P`` pretty ``3.4×10⁹ kilogram·meter/second²``
``H`` HTML ``3.4×10<sup>9</sup> kilogram meter/second<sup>2</sup>``
``L`` latex ``3.4\\times 10^{9}\\ \\frac{\\mathrm{kilogram} \\cdot \\mathrm{meter}}{\\mathrm{second}^{2}}``
``Lx`` latex siunitx ``\\SI[]{3.4e+09}{\\kilo\\gram\\meter\\per\\second\\squared}``
``C`` compact ``3.4e+09 kilogram*meter/second**2``
======= =============== ======================================================================
These examples are using `g`` as numeric modifier. :py:class:`Measurement` are also affected
by these modifiers.
Quantity modifiers
------------------
======== =================================================== ================================
Modifier Meaning Example
======== =================================================== ================================
``#`` Call :py:meth:`Quantity.to_compact` first ``1.0 m·mg/s²`` (``f"{q:#~P}"``)
======== =================================================== ================================
Unit modifiers
--------------
======== =================================================== ================================
Modifier Meaning Example
======== =================================================== ================================
``~`` Use the unit's symbol instead of its canonical name ``kg·m/s²`` (``f"{u:~P}"``)
======== =================================================== ================================
Magnitude modifiers
-------------------
Pint uses the :ref:`format specifications <formatspec>`. However, it is important to remember
that only the type honors the locale. Using any other numeric format (e.g. `g`, `e`, `f`)
will result in a non-localized representation of the number.
Custom formats
--------------
Using :py:func:`pint.register_unit_format`, it is possible to add custom
formats:
.. doctest::
>>> @pint.register_unit_format("Z")
... def format_unit_simple(unit, registry, **options):
... return " * ".join(f"{u} ** {p}" for u, p in unit.items())
>>> f"{q:Z}"
'2.3e-06 kilogram ** -1 * meter ** 3 * second ** -2'
where ``unit`` is a :py:class:`dict` subclass containing the unit names and
their exponents, ``registry`` is the current instance of :py:class:``UnitRegistry`` and
``options`` is not yet implemented.
You can choose to replace the complete formatter. Briefly, the formatter if an object with the
following methods: `format_magnitude`, `format_unit`, `format_quantity`, `format_uncertainty`,
`format_measurement`. The easiest way to create your own formatter is to subclass one that you
like and replace the methods you need. For example, to replace the unit formatting:
.. doctest::
>>> from pint.delegates.formatter.plain import DefaultFormatter
>>> class MyFormatter(DefaultFormatter):
...
... default_format = ""
...
... def format_unit(self, unit, uspec, sort_func, **babel_kwds) -> str:
... return "ups!"
...
>>> ureg.formatter = MyFormatter()
>>> ureg.formatter._registry = ureg
>>> str(q)
'2.3e-06 ups!'
By replacing other methods, you can customize the output as much as you need.
SciForm_ is a library that can be used to format the magnitude of the number. This can be used
in a customer formatter as follows:
.. doctest::
>>> from sciform import Formatter
>>> sciform_formatter = Formatter(round_mode="sig_fig", ndigits=4, exp_mode="engineering")
>>> class MyFormatter(DefaultFormatter):
...
... default_format = ""
...
... def format_magnitude(self, value, spec, **options) -> str:
... return sciform_formatter(value)
...
>>> ureg.formatter = MyFormatter()
>>> ureg.formatter._registry = ureg
>>> str(q * 10)
'23.00e-06 meter ** 3 / second ** 2 / kilogram'
.. _SciForm: https://sciform.readthedocs.io/en/stable/
|