t=Template('''These characters get replaced: _variable, _function
This line is then formatted: {0} ZIP _variable , _function
And this one is iterated: {0} ZIP _iter , _function''')
t.fill(_variable=2,_function="lambda i:i*10",_iter=range(2))
t
What happened? When calling t.fill
, _variable
was replaced with 2
everywhere it appeared in the template, similarly with _function
. This includes after the custom function ZIP
, where they appear as arguments.
After this substitution, ZIP
formatted the text preceding it ({0}
) with the result of _function(_variable)
, i.e, format("{0}",(lambda i:i*10)(2))
.
In the next line, ZIP
repeatedly formatted the text preceding it ({0}
) with the result of _function(_iter)
, i.e, '\n'.join([format("{0}",(lambda i:i*10)(j)) for j in range(2)])
.
Before we go into more detail on these functions, let's examine the template object:
t.__dict__
The temp
attribute stores the un-formatted text handed to Template
. The plate
attribute stores the formatted lines as a list of strings. The object also stores any kwargs as attrs. Finally, text()
attribute concatenates the formatted text into a string separated by newlines, and is used as the __repr__
.
Let's see how ZIP
works:
ZIP('{0}',range(10),lambda i:i)
When embedded in the Template
, ZIP
treats the text proceeding it as an iterable or a single-substitution, and any text after the ,
as a list of functions. These functions take the iterable as an argument, and format the text preceding ZIP
with their evaluation on the iterable. They do not need to be lambdas - any callable will do. This makes embedding ZIP
into other text documents a useful way to modularize the formatting of text, and automate code blocks in other languages which lack Python flexibility.
Other helper functions enabling this process are as follows:
replace('''result={0}; ZIP _myvar,lambda i:i*10''',_myvar=2)
txt=txt2lst('''var=_myvar
result={0}; ZIP _myvar,lambda i:i*10
''')
txt
for i,l in enumerate(txt):
txt[i]=replace(l,_myvar=2)
getEvals(txt,funcs=['ZIP'])
These are then packaged into the Template
class, which we give another arbitrary example of here:
t=Template('''Filling out _stuff
which {0}{1} is ZIP 1, lambda t:'iterates ' , _arbitrarily
{0} ZIP range(3), lambda t: "much"
easier
since we can embed any keyword, iterable, and function anywhere.
''',_stuff='stuff',_arbitrarily="lambda t: 'arbitrarily'")
t
t.fill('we can append, _too',_too='too!',append=True)
t
Finally, a Template
will attempt to auto-load a file if the input is a filename, e.g Template('template.txt')
will load the file template.txt
if it exists in the current directory, and use that as the string to format.