File: formatting.rst

package info (click to toggle)
python-pint 0.25-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,916 kB
  • sloc: python: 20,307; makefile: 149
file content (148 lines) | stat: -rw-r--r-- 5,602 bytes parent folder | download
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/