"%(a)s ... %(b)s" % {'a': foo, 'b': '%(b)s'}

Gerrit Holl gerrit.holl at pobox.com
Sat Dec 4 17:09:19 EST 1999


Michael Hudson wrote:
> Gerrit Holl <gerrit.holl at pobox.com> writes:
> 
> > Hello,
> > 
> > I'm facing the following problem. I set __version__ and now I set a string
> > like this:
> > 
> > MAIL = '''From: someone <%(email)s>
> > Subject: test
> > 
> > this is feedback.py %(version)
> > ''' % {'version': __version__}
> > 
> > This raises a KeyError. I have to type:
> > ... % {'version': __version__, 'email': '%(email)s'}
> > 
> > This is ugly! Isn't there a better way to fill in just SOME of the %(...)s
> > values in a string and leave the rest as is?
> 
> If you know the order you will be filling the fields in, then you can
> double up the `%' signs, like:
> 
> >>> __version__ = 1
> >>> t = "%(version)s %%(email)s"%{"version":__version__}
> >>> t
> '1 %(email)s'

>>> s='%% sign, %%(email)s, %(version)s, %%%% sign'
>>> s2=s % {'version': 1}
>>> print s2
% sign, %(email)s, 1, %% sign
>>> print s2 % {'email': 'gerrit at nl.linux.org'}
{'email': 'gerrit at nl.linux.org'}ign, gerrit at nl.linux.org, 1, % sign

kan lead to very unexspected things ;-)

This can lead to ugly Quoting hell!

> 
> or you could do
> 
> >>> class NotQuiteDict:
> 	def __getitem__(self,item):
> 		if item == "version":
> 			return "1"
> 		else:
> 			return "%%(%s)s"%item
> 
> 		
> >>> c = NotQuiteDict()
> >>> "%(version)s %(email)s"%c
> '1 %(email)s'
> 
> which obviously needs generalisation, but I hope you get the idea.

>>> class NotQuiteDict:
...    dict = {}
...    def __init__(self, **kw):
...        for k, w in kw.items():
...            self.dict[k]=w
...	# whitespace for readability :-)
...    def __getitem__(self, item):
...        if item in self.dict.keys():
...            return self.dict[item]
...        else:
...            return '%%(%s)s' % item

>>> print '%(a)s, %(b)s' % NotQuiteDict(a='aaaa')
aaaa, %(b)s


But _why_ isn't this permitted:
>>> print '%(a)s, %(b)s' % {'a': 'aaaa'}
Traceback (innermost last):
  File "<stdin>", line 1, in ?
KeyError: b

Can't Python automatticaly detect there's no B so leave it blank? Why doesn't
Python do this?

regards,
Gerrit.

-- 
"However, complexity is not always the enemy."

  -- Larry Wall (Open Sources, 1999 O'Reilly and Associates)
 10:59pm  up 36 min,  8 users,  load average: 0.00, 0.01, 0.05




More information about the Python-list mailing list