Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #7092 > unrolled thread
| Started by | Chris Rebert <clp2@rebertia.com> |
|---|---|
| First post | 2011-06-06 09:21 -0700 |
| Last post | 2011-06-07 17:47 +1000 |
| Articles | 6 — 4 participants |
Back to article view | Back to comp.lang.python
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: new string formatting with local variables Chris Rebert <clp2@rebertia.com> - 2011-06-06 09:21 -0700
Re: new string formatting with local variables Ben Finney <ben+python@benfinney.id.au> - 2011-06-07 10:11 +1000
Re: new string formatting with local variables Ian Kelly <ian.g.kelly@gmail.com> - 2011-06-06 18:31 -0600
Re: new string formatting with local variables Ian Kelly <ian.g.kelly@gmail.com> - 2011-06-06 18:38 -0600
Re: new string formatting with local variables Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-06-07 03:57 +0000
Re: new string formatting with local variables Ben Finney <ben+python@benfinney.id.au> - 2011-06-07 17:47 +1000
| From | Chris Rebert <clp2@rebertia.com> |
|---|---|
| Date | 2011-06-06 09:21 -0700 |
| Subject | Re: new string formatting with local variables |
| Message-ID | <mailman.2491.1307377282.9059.python-list@python.org> |
On Mon, Jun 6, 2011 at 9:15 AM, Jabba Laci <jabba.laci@gmail.com> wrote:
> Hi,
>
> I'd like to simplify the following string formatting:
>
> solo = 'Han Solo'
> jabba = 'Jabba the Hutt'
> print "{solo} was captured by {jabba}".format(solo=solo, jabba=jabba)
> # Han Solo was captured by Jabba the Hutt
>
> What I don't like here is this: "solo=solo, jabba=jabba", i.e. the
> same thing is repeated. In "solo=solo", the left part is a key and the
> right part is the value of a local variable, but it looks strange.
>
> I'd like something like this:
> print "{solo} was captured by {jabba}".format(locals()) # WRONG!
>
> But it doesn't work.
>
> Do you have any idea?
print "{solo} was captured by {jabba}".format(**locals()) # RIGHT
You must use prefix-** in the call to unpack the mapping as keyword arguments.
Note that using locals() like this isn't best-practice.
Cheers,
Chris
--
http://rebertia.com
[toc] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2011-06-07 10:11 +1000 |
| Message-ID | <87zklu1ox6.fsf@benfinney.id.au> |
| In reply to | #7092 |
Chris Rebert <clp2@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?
--
\ “If you write the word ‘monkey’ a million times, do you start |
`\ to think you're Shakespeare?” —Steven Wright |
_o__) |
Ben Finney
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2011-06-06 18:31 -0600 |
| Message-ID | <mailman.2511.1307406733.9059.python-list@python.org> |
| In reply to | #7120 |
On Mon, Jun 6, 2011 at 6:11 PM, Ben Finney <ben+python@benfinney.id.au> wrote: >> 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? http://stackoverflow.com/questions/1550479/python-is-using-vars-locals-a-good-practice
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2011-06-06 18:38 -0600 |
| Message-ID | <mailman.2512.1307407121.9059.python-list@python.org> |
| In reply to | #7120 |
On Mon, Jun 6, 2011 at 6:11 PM, Ben Finney <ben+python@benfinney.id.au> wrote:
> Chris Rebert <clp2@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.
If you're using an object namespace, then you can just do this:
print("{o.solo} was captured by {o.jabba}".format(o=self))
That looks a lot cleaner to me than passing in **vars(self). For
locals(), I can see the appeal, but I tend to avoid it because it has
the same icky feeling as doing an import *.
Cheers,
Ian
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2011-06-07 03:57 +0000 |
| Message-ID | <4deda1c6$0$29980$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #7120 |
On Tue, 07 Jun 2011 10:11:01 +1000, Ben Finney wrote:
> Chris Rebert <clp2@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
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2011-06-07 17:47 +1000 |
| Message-ID | <871uz613rl.fsf@benfinney.id.au> |
| In reply to | #7132 |
Steven D'Aprano <steve+comp.lang.python@pearwood.info> writes:
> On Tue, 07 Jun 2011 10:11:01 +1000, Ben Finney wrote:
>
> > 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.
[…]
>
> 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?
The names are explicit; they're in the format string. It's because I
don't want to repeat the names several times that I'm making use of the
dictionary provided by ‘vars()’.
> 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)
See, repeating those name references makes *me* hinky. I used those
names because they refer to things I've already named.
--
\ “The difference between religions and cults is determined by |
`\ how much real estate is owned.” —Frank Zappa |
_o__) |
Ben Finney
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web