private variables/methods

Harri Pesonen fuerte at sci.fi
Mon Oct 13 22:54:14 EDT 2003


Sean Ross wrote:

> "Harri Pesonen" <fuerte at sci.fi> wrote in message
> news:SMDib.231$8j.6 at reader1.news.jippii.net...
> 
>>Christopher Koppler wrote:
>>
>>>Hmmm, asking naively: why not make global (or some better name, I
>>>don't have any good ideas however) the self of the current module -
>>>i.e. instead of
>>>
>>>def fun():
>>>  global x
>>>  x = somevalue
>>>
>>>or your import, you'd use
>>>
>>>def fun():
>>>  global.x = somevalue
> 
> Christopher:
> 
> Hi.
> You couldn't use "global" that way for backwards compatability reasons.
> Still, I like the overall idea.
> 
> [snip]
> 
>>Sounds good to me. So if you have now
>>
>>a = 1
>>def b():
>>    a = 2
>>
>>This would cause a compiler warning that a global "a" already exists.
> 
> Harri:
> 
> Hi.
> Actually, I don't think that is what's intended. Rather, if you want to use
> the global variable a, you will need to access it through the current module
> object, which can be referenced using global, i.e.,
> 
> a = 1
> def b():
>     global.a = 2 # rebinds the global variable a
>     a = 3 # binds a new local variable a, the global variable a is
> unaffected.
>     print "a values: global = %s; local = %s"%(global.a, a)
> 
> #output
> a values: global = 2; local = 3
> 
> the local and global variables a will not be confused, because the global
> variable a can only ever be referenced in the local scope via the current
> module reference ("global"). Meaning, if you want to use a global variable
> in a scope other than at the module level , you'll have to preface it with
> "global.".
> 
>>So
>>the programmer should write either
>>
>>def b():
>>    global.a = 2
>>
>>or
>>
>>def b():
>>   local.a = 2
>>
>>The latter of course creates a new local variable with the same name.
>>After this it is OK to use just "a" without "local" prefix?
>>
>>def b():
>>    local.a = 2
>>    a = 3
> 
> So, continuing from the explanation above, you will not have to say "local.a
> = 2" to bind a local variable. All variables will be local by default.
> Variables from other namespaces (such as globals) will have to be explicitly
> resolved (e.g. "global.a = 2")
> 
>>How about the following:
>>
>>def b():
>>global.a = 2
>>    a = 3
>>
>>Is the second "a" still global?
> 
> No.
> 
>>The idea with "Option Explicit" gets around this differently. The
>>following creates a new local variable:
>>
>>def b():
>>    var a = 2
>>
>>While the following refers to the global variable, if there is no local
>>variable with the same name:
>>
>>def b():
>>    a = 2
>>
>>This would be more beautiful.
> 
> Making a variable local by default, and requiring that globals be accessed
> explicitly seems like a better path to me. As far as I know, the use of
> globals is generally discouraged. So a lot of people try to avoid using them
> in code, when they can. But local variables occur all the time. Using
> "Option Explicit" would seem to be making you write more code for something
> that happens more often (local variable binding), and less code for
> something that is discouraged and should be happening less often (global
> variable rebinding).  But maybe thats just me...

I agree with you. But the original problem (at least mine) was that the 
following code has a bug that the compiler could easily detect and warn.

a = 1
def b():
     a = 2

Perhaps the above bug happens with novice Python developers only. But my 
idea of compiler warning and "global.a = 2" and "local.a = 2" (or "var a 
= 2") would solve it. I wonder how many unnecessary warnings this would 
cause in the current code base, and how many bugs it would detect.

It is a bit difficult for novice Python developers to understand why 
accessing global variables is OK but modifying them is not, especially 
if you just write a short script like the above. There is no such 
restriction in any other language I know. I agree that modifying global 
variables is usually bad, though. But it would be more beautiful if 
accessing and modifying would happen with the same syntax ("global." 
prefix or not). Every other language checks first the locals and then 
globals and modifies what it finds first, and gives error if it can't 
find it. So the above code should work as it is, without any extra 
"global" keywords. But this is impossible because of the current code 
base... it seems that there is no easy solution here.

Harri





More information about the Python-list mailing list