Python Safe string templates for a nested dict object

I have a complex nested dict object, for example:

value = { 'a': '100', bits: { 1: 'alpha', 2: 'beta', 3: ['31', '32', 901] } } 

I need to "securely" format it using a template. If no keys are found, just silently ignore the {} holders. Keys may be missing, and I do not want to raise KeyErrors. The problem is that string.Template cannot process the same functions as str.format. The str.format used is something like:

 "a=${a}, b1={bits[1]}, b31={bits[3]}, b9={bits[9]}".format(**value) 

and the conclusion should be:

 "a=100, b1=alpha, b31=(31, 32, 901), b9=" 

I don't need fancy loops or if / else conditions. Just simple formats with subdisks.

What options do I have? I prefer to use the built-in modules as much as possible or a very small library.

This is not a web application, so no, if possible, I want to avoid loading lib like jinja2, just for that.

+4
source share
2 answers

Write your own formatter:

 In [1]: from string import Formatter In [2]: value = { ...: 'a': '100', ...: 'bits': { ...: 1: 'alpha', ...: 2: 'beta', ...: 3: ['31', '32', 901]}} In [3]: class YourFormatter(Formatter): ...: def get_value(self, field_name, args, kwargs): ...: return kwargs.get(field_name, '') ...: ...: def get_field(self, field_name, args, kwargs): ...: first, rest = field_name._formatter_field_name_split() ...: obj = self.get_value(first, args, kwargs) ...: ...: for is_attr, i in rest: ...: if is_attr: ...: obj = getattr(obj, i) ...: else: ...: obj = obj.get(i, '') ...: return obj, first ...: In [4]: fmt = YourFormatter() In [5]: fmt.format("a={a}, b1={bits[1]}, b31={bits[3]}, b9={bits[9]}", **value) Out[5]: "a=100, b1=alpha, b31=['31', '32', 901], b9=" 
+1
source

The only way to do this is to write a wrapper class that implements the dict and sequence protocols, wrap any list or return value in the same class, and catch any KeyError or IndexError exceptions.

Then your call will become "…".format(**DefaultingWrapper(value)) .

+1
source

Source: https://habr.com/ru/post/1479873/


All Articles