private variables/methods

Sean Ross sross at connectmail.carleton.ca
Tue Oct 14 00:39:38 EDT 2003


"Harri Pesonen" <fuerte at sci.fi> wrote in message
news:aAJib.269$8j.181 at reader1.news.jippii.net...
>
> 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
>

Hi.
I see what your saying, though I wouldn't consider that so much a "bug"
as much as I would consider it a misunderstanding of how binding
works in Python. But, yeah, if you wrote that expecting to bind the
global variable 'a' to 2, I guess you'd have a bug :)

[snip]
> 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.

I suppose it might be. I didn't find that, but I can see how it could be
true.

> There is no such restriction in any other language I know.

I'm thinking that the languages you're speaking of require you to declare
your variables before (or as) you bind them. Python doesn't. And most
people who use Python _really_appreciate_ that. So, unfortunately, there
likely will not be much head-way gained in trying to get variable
declarations of any form added to the language (i.e., var a = 3, or even
local.a = 3). Just so you know.

Also, just to give you an example of another language that _does_ have
the same "problem" we're discussing, here's some Ruby code:

a = 1
def b()
    a = 2
end
b()
print a
# outputs: 1

The first 'a' is bound as a local variable in the module scope, while the
second is bound as a local variable in the method (yep, that's a method,
not a function) scope of 'b'. Pretty much the same thing as what happens
in Python. But, then, that first 'a' really isn't global, in the Ruby sense.
To make it global we need to use '$a'.

$a = 1
def b()
    $a = 2
end
b()
print $a
# outputs: 2

That works the way you were hoping. And there's no confusion between
what's global and what's local. But, then, you've also got to use that sigil
all the time (and Python folk don't take kindly to sigils ;). Which would be
pretty much comparable to the "global.a" idea. It's different from the
current "global a" method, since you can't have a local variable 'a'
once you've used the global statement. With "global.a" or "$a", you could.

> 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.
>

For accessing, Python, essentially,  first checks locals and then globals.
For modifying...no. Essentially, "a = 2" works _something_like_
locals()['a'] = 2. I don't think Python tries to look up 'a' during a
binding
operation (but I could be wrong :). To do what you're advocating, it'd have
to, and that would probably slow things down.

So, yeah, there's no easy solution. The "global.a" idea seems okay. You
don't have to declare your variables, and you can't confuse local and
global variables, because you have to use the global namespace directly
to access global variables. But, then, you have to use the global
namespace directly to access global variables, heh. So, you're code
becomes more verbose. You could go the Ruby route and introduce a
sigil to denote global, but I don't see that happening in this language. And
the look-up before binding approach probably won't be happening any
time soon either. Oh well.

C'est la vie.
Sean






More information about the Python-list mailing list