Python string patterns: what are legal characters?

I can not understand what is happening with string patterns :

t = Template('cannot teach an ${dog.old} ${tricks.new}. ${why} is this ${not} working') print t.safe_substitute({'dog.old': 'old dog', 'tricks.new': 'new tricks', 'why': 'OH WHY', 'not': '@#%@#% NOT'}) 

Fingerprints:

 cannot teach an ${dog.old} ${tricks.new}. OH WHY is this @#%@#% NOT working 

I thought that parentheses handle arbitrary strings. What characters are allowed in braces and is there a way to subclass Template to do what I want?

+4
source share
3 answers

From the documentation ...

Identifier

$ refers to a placeholder that matches the matching identifier key. By default, the "identifier" must contain the Python identifier. The first non-identifier character after the $ character completes this placeholder specification.

A period is a non-identifier character, and curly braces are simply used to separate an identifier from adjacent non-identifier text.

+4
source

Yeah, I tried this experiment:

 from string import Template import uuid class MyTemplate(Template): idpattern = r'[az][_a-z0-9]*(\.[az][_a-z0-9]*)*' t1 = Template('cannot teach an ${dog.old} ${tricks.new}. ${why} is this ${not} working') t2 = MyTemplate('cannot teach an ${dog.old} ${tricks.new}. ${why} is this ${not} working') map1 = {'dog.old': 'old dog', 'tricks.new': 'new tricks', 'why': 'OH WHY', 'not': '@#%@#% NOT'} map2 = {'dog': {'old': 'old dog'}, 'tricks': {'new': 'new tricks'}, 'why': 'OH WHY', 'not': '@#%@#% NOT'} print t1.safe_substitute(map1) print t1.safe_substitute(map2) print t2.safe_substitute(map1) print t2.safe_substitute(map2) 

which prints

 cannot teach an ${dog.old} ${tricks.new}. OH WHY is this @#%@#% NOT working cannot teach an ${dog.old} ${tricks.new}. OH WHY is this @#%@#% NOT working cannot teach an old dog new tricks. OH WHY is this @#%@#% NOT working cannot teach an ${dog.old} ${tricks.new}. OH WHY is this @#%@#% NOT working 

this is how the third one works ( print t2.safe_substitute(map1) ).

+3
source

Python interprets . in your name as "access to the old field of the dog instance". Try _ or make a dog object with the old field.

AFAIR, only valid identifiers and . are safe between braces.

[EDIT] On the page you link to:

${identifier} equivalent to $identifier . This is necessary when valid identifier characters follow the placeholder, but are not part of the placeholder, for example, "${noun}ification" .

and

"identifier" must contain the Python identifier.

which means: it must be a valid identifier.

[EDIT2] It seems the identifier is not being parsed as I thought. Therefore, you must specify a simple valid Python identifier in braces (and you cannot use the field attribute syntax) unless you create your own implementation of the Template Class .

+1
source

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


All Articles