Overriding a global

Joshua Landau joshua.landau.ws at gmail.com
Wed Dec 14 11:54:09 EST 2011


On 14 December 2011 10:14, Jean-Michel Pichavant <jeanmichel at sequans.com>wrote:

> Joshua Landau wrote:
>
>  On 13 December 2011 13:30, Jean-Michel Pichavant <jeanmichel at sequans.com<mailto:
>> jeanmichel at sequans.com**>> wrote:
>>
>>    writing
>>
>>    x = 1
>>
>>    def spam():
>>      x = 2
>>
>>    is in general a bad idea. That was my point.
>>
>>
>> Why? I have a few (probably wrong) guesses.
>>
>> Because you expect it to be the same every time you use it?
>> Well, then this should be "in general a bad idea":
>> x = 1; print(x); x = 2; print(x)
>>
> you're changing the value of x, that's fine. In the example above, the
> assignement is not the problem. The problem is that you create 2 different
> 'x', one in globals(), and one in locals(). Using the same name within 2
> implicit namespaces is a bad idead in general because it can be difficult
> to know which one is used.
>
> If you want to have fun, try this code, prepared to be amazed. There's
> something funny with the global statement, it's applied on the whole block
> no matter where it is stated in the block.
> x=1 # global
>
> def spam():
>   x = 2 # local (or so you may think)
>   print x
>   global x # I need to use the global one now
>   print x
>   print locals()
>

<stdin>:3: SyntaxWarning: name 'x' is assigned to before global declaration

I think it's a null point. We're not talking about "globals" being wrong
(or was this poor design) for efficiency reasons. There's an error there
for reason.


> For more fun you could create a 'x' name in __builtin__ and import it so
> that people never know which x you are using.
>
>  Even though it makes total sense to me.
>>
>> Is it because it's used to different purpose between similarly-looking
>> functions?
>> This looks fine, though:
>> def func1(): x=1; print(x)
>> def func2(): x=2; print(x)
>>
>> Is it because it looks like a reassignment of the more global x?
>> I don't have an example here but, simply put, I don't believe this. We
>> can use "id" as our own local variable without thinking that we're
>> tampering with "__builtins__.id". I don't see it as much of a leap from
>> builtin to global (except that you /*can*/ do "dir = 1; del dir; dir"
>> without error).
>>
>>
>> That said, I'm sorta' just guessing the reason you might think it's a bad
>> idea.
>>
>
> The problem makes little sense when using names like x or func1. Besides
> namespace issues, naming 2 *different objects* with the same meaningful
> name is usually a bad idea and points the fact that your names are no that
> meaningful. To go back to the original post, having a 'logger' that may
> name 2 different logger object during the execution is a bad idea. One
> quick way to fix it is to name the logger 'currentLogger', this way you
> warn the reader that the logger named by curentLogger may change over time.
>
> As someone sugggested in this thread one other option is to use a
> different name for the second logger.


So the only problem is that "x" isn't meaningful?

def countToTen():
     for number in range(1, 10): print(number)

def countToTwenty():
     for number in range(1, 20): print(number)

.. Looks fine to me.

Using currentLogger is just padding, in my opinion. *Every *value is
"current<value>". That changes nothing. As long as you never infer that
"logger" is static or totally global (no "global logger" in global
namespace or terming it "LOGGER") I would never assume as much, as with
every other variable I see. Unless I see "global <var>" in a function, I
need to hold the belief that <var> can change.

In regards to a second name - yes this could work and in many cases would
be desirable, but it doesn't really help this circumstance. [assume, for a
moment, a lot of functions used a local logger] "localLogger" would tell
you very little about what the logger actually *is*. You still have to look
that up. [end assumption] Additionally, this would make changing a logger
that uses the default to a local one *much* harder. And don't say "but you
can just always make a local copy", as then you lose the advantage of a
global.

Typing something like "logger = childLogger(id)" to the start of a function
call *is explicit*, it's clean, and it makes sense to have a default that's
global. You're not appending cruft ("current") and you have consistency. If
you added "logger = globalLogger" to every function start as well you can
argue that it's better. I agree it's more explicit. But then you
lose unneeded if only a small portion of your code localises logger. But I
would recommend it if a large portion of code used local variants.

AND:

> The next time I'll illustrate meaningful names,  I'll write a 3000 lines
> function, just to be sure no one states that my point does'nt apply to a
> function named spam which only counts from 1 to 3.
> And don't answer that the spam function above does not count from 1 to 3,
> I know it doesn't.


You're acting in sarcasm to a comment on scale, when you yourself said that
one of my comments was invalid due to names that were scaled down for
exampling. It seems a bit hypocritical to me. That said, not all functions
are long. If the short ones use short names that's fine: I'm pretty sure
you said it's not.

And in regards to the link:
1) __add__ says otherwise (technically, the operator "+"). It's rarely
confused me.
2) That's not what we're discussing. As it said: "As long as the parameter
lists are semantically equal and the desired result is the same, all is
well." They're doing semantically the same thing (to different log levels)
with the same parameter lists and they're not class methods. You /could/
say that the semantics are different, but classes act in a context in the
same way local variables can be thought of doing, and semantics are the
same for them. Instead of a different self, it's a different log
file/level. Same semantics.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20111214/a8e00cb0/attachment-0001.html>


More information about the Python-list mailing list