views:

111

answers:

2

Looking for best practice advice on what string substitution technique to use when using gettext(). Or do all techniques apply equally?

I can think of at least 3 string techniques:

1) Classic "%" based formatting:

"My name is %(name)s" % locals()

2) .format() based formatting:

"My name is {name}".format( locals() )

3) string.Template.safe_substitute()

import string template = string.Template( "My name is ${name}" ) template.safe_substitute( locals() )

The advantage of the string.Template technique is that a translated string with with an incorrectly spelled variable reference can still yield a usable string value while the other techniques unconditionally raise an exception. The downside of the string.Template technique appears to be the inability for one to customize how a variable is formatted (padding, justification, width, etc).

+2  A: 

Actually I would prefer to get an exception during my tests, to fix the error as soon as possible -- "errors should not pass silently". So I consider that approach (2) is the best one in modern Python (which supports the readable and flexible format), and approach (1) a probably inevitable fall-back if you're stuck supporting older Python releases (where % was "the" way to do flexible formatting -- finding, or coding, some backport of format would be the main alternative).

Alex Martelli
Alex: Thanks for your answer. We had a small section of code that was using user customizable strings as a pseudo template facility, hence my attraction to the string.Template technique. We're going to bite the bullet and use a real template module for this task.
Malcolm
+1  A: 

Don't have incorrectly spelled variable names - that's what testing is for.

On the face of it, displaying something seems better than throwing an exception, but sooner or later one of those mistranslations is bound to cause offence to some user.

.format() is the way to go these days.

Reconsider passing locals() straight into the translation. It will save you worrying about what happens if someone works out a way to do something sneaky with self in one of the translations.

gnibbler
Gnibbler: Thanks for the reminder about locals(). Originally I used locals() as a quick and dirty way to explain my question. However, your comment caused me to go back and do a quick code review to make sure this coding practice hadn't creeped into our code. To my surprise there were several places where we had actually used such a technique.
Malcolm