/
printer.py
65 lines (59 loc) · 2.29 KB
/
printer.py
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
from itertools import chain
class Printer(object):
_str = str # set to unicdoe int UnicodePrinter for Python 2
_default_settings = dict(
with_param=True,
with_name=True,
fallback_print_fn=str,
Reaction_param_separator="; ",
Reaction_coeff_space=" ",
Reaction_around_arrow=(" ", " "),
magnitude_fmt=lambda x: "%.3g" % x,
)
_default_setting_factories = dict(
substances=dict,
colors=dict, # substance key -> (bg-color, border-color), 6 char hex colors
)
_default_setting_attrs = dict(
Reaction_coeff_fmt="_str",
Reaction_formula_fmt="_str",
unit_fmt="_str",
)
printmethod_attr = (
None # e.g. '_html' or '_unicode', allows object local printing logic
)
def __init__(self, settings=None):
self._settings = dict(self._default_settings, **(settings or {}))
for k, v in self._default_setting_factories.items():
if k not in self._settings:
self._settings[k] = v()
for k, v in self._default_setting_attrs.items():
if k not in self._settings:
self._settings[k] = getattr(self, v)
for k in self._settings:
if k not in chain(
self._default_settings,
self._default_setting_factories,
self._default_setting_attrs,
):
raise ValueError(
"Unknown setting: %s (missing in default_settings)" % k
)
def _get(self, key, **kwargs):
return kwargs.get(key, self._settings[key])
def _print(self, obj, **kwargs):
for cls in type(obj).__mro__:
print_meth = "_print_" + cls.__name__
if hasattr(self, print_meth):
return getattr(self, print_meth)(obj, **kwargs)
for PrintCls in self.__class__.__mro__:
_attr = getattr(PrintCls, "printmethod_attr", None)
if _attr and hasattr(obj, _attr):
return getattr(obj, _attr)(self, **kwargs)
fn = self._get("fallback_print_fn", **kwargs)
if fn:
return fn(obj)
else:
raise ValueError("Don't know how to print obj of type: %s" % type(obj))
def doprint(self, obj):
return self._print(obj)