On Tue, 07 Jun 2011 10:11:01 +1000, Ben Finney wrote: > Chris Rebert <c...@rebertia.com> writes: > >> print "{solo} was captured by {jabba}".format(**locals()) # RIGHT > > I tend to use ‘u"foo {bar} baz".format(**vars())’, since ‘vars’ can also > take the namespace of an object. I only need to remember one “give me > the namespace” function for formatting. > >> You must use prefix-** in the call to unpack the mapping as keyword >> arguments. Note that using locals() like this isn't best-practice. > > Who says so, and do you find their argument convincing? Do you have a > reference for that so we can see why?
It's a code smell. Why is this code messing with locals() instead of using names explicitly? Is it possible that this code will attempt to modify locals()? I need to look twice to be sure its safe. Why do you need to pass *all* of the locals if only two names are used? Seeing an arbitrary large number of arguments passed to a piece of code that only requires two makes me feel hinky. It's not that it's *necessarily* bad, in and of itself, but it should make you take a second, closer look at it. Where possible, I'd rather be explicit about which names I want: solo = "Han Solo" jabba = "Jabba the Hutt" "{hero} was captured by {villain}.".format(hero=solo, villain=jabba) It also strikes me as potentially wasteful to unpack an arbitrarily large dict into keyword arguments, and then (presumably) have the format method pack them back into a dict again. Again, this might be trivial... but it might not be. No way of knowing just by reading that line of code, hence a code smell. Oh, and there's even a failure mode for this **locals() or **vars() pattern, at least for CPython. If you do this in production code, I hate you, but it can happen: >>> globals()[42] = "spam spam spam" # Ouch! >>> vars() {'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', 42: 'spam spam spam', '__doc__': None, '__package__': None} >>> def f(**kwargs): ... print kwargs ... >>> >>> f(**vars()) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: f() keywords must be strings -- Steven -- http://mail.python.org/mailman/listinfo/python-list