views:

356

answers:

3

Following code:

def __init__(self, url, **kwargs):
    for key in kwargs.keys():
     url = url.replace('%%s%' % key, str(kwargs[key]))

Throws the following exception:

File "/home/wells/py-mlb/lib/fetcher.py", line 25, in __init__
url = url.replace('%%s%' % key, str(kwargs[key]))
ValueError: incomplete format

The string has a format like:

http://www.blah.com?id=%PLAYER_ID%

What am I doing wrong?

+5  A: 

You probably want the format string %%%s%% instead of %%s%.

Two consecutive % signs are interpreted as a literal %, so in your version, you have a literal %, a literal s, and then a lone %, which is expecting a format specifier after it. You need to double up each literal % to not be interpreted as a format string, so you want %%%s%%: literal %, %s for string, literal %.

Adam Rosenfield
Ah yes! Close, but %%%s%% is what I wanted: so it's a percent, followed by the actual key in kwargs, followed by a percent. But now that I look at %%%s%% in my code, it looks really annoying and I'm wondering if there's a nice way of doing what I am trying to do.
Wells
Gotcha, fixed now.
Adam Rosenfield
@Wells: try "%{0}%".format( kwargs[key] )
Adrien Plisson
The nicer way is: url.replace('%'+key+'%', str(kwargs[key]))
Ned Batchelder
+2  A: 

you need to double the percentage sign to escape it:

>>> '%%%s%%' % 'PLAYER_ID'
'%PLAYER_ID%'

also when iterating over the dictionary you could unpack values in the for statement like this:

def __init__(self, url, **kwargs):
    for key, value in kwargs.items():
        url = url.replace('%%%s%%' % key, str(value))
SilentGhost
In general, Python 2.x code should default to using `iteritems` over `items`; the latter generates a list in memory while the former returns a generator that iterates the map. It won't make a difference here really, but it's good to have the right habit.Besides that, looks good.
Walter Mundt
huh? where do you see indications of the py2k code? it's py3k, and there no `iteritems` in existence.
SilentGhost
+1  A: 

Adam almost had it right. Change your code to:

def __init__(self, url, **kwargs):
    for key in kwargs.keys():
        url = url.replace('%%%s%%' % key, str(kwargs[key]))

When key is FOO, then '%%%s%%' % key results in '%FOO%', and your url.replace will do what you want. In a format string, two percents results in a percent in the output.

Ned Batchelder