Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

private variables/methods

1 view
Skip to first unread message

gabor

unread,
Oct 9, 2003, 3:42:29 AM10/9/03
to
hi,

as far as i know in python there aren't any private (i mean not accessible
from the outside of the object) methods/fields.

why?

in java/c++ i can make a method private, this way unaccessible for the outside
world. i think it helps a lot to make for example a library more robust.

i know that there is some kind of notation to make a method/field private,
but one can still overwrite it's value.

what's the reason for this?

i'l mostly interested in the design reasons.

thanks,
gabor

--
That's life for you, said McDunn. Someone always waiting for someone
who never comes home. Always someone loving something more than that
thing loves them. And after awhile you want to destroy whatever
that thing is, so it can't hurt you no more.
-- R. Bradbury, "The Fog Horn"

Dave Benjamin

unread,
Oct 9, 2003, 4:12:29 AM10/9/03
to
In article <mailman.106568533...@python.org>, gabor wrote:
> as far as i know in python there aren't any private (i mean not accessible
> from the outside of the object) methods/fields.
>
> why?

No offense, but this is like the 4000th time someone has asked that question
here. Could you try searching Google groups first?

Dave

--
.:[ dave benjamin (ramenboy) -:- www.ramenfest.com -:- www.3dex.com ]:.
: d r i n k i n g l i f e o u t o f t h e c o n t a i n e r :

gabor

unread,
Oct 9, 2003, 8:06:06 AM10/9/03
to
On Thu, 2003-10-09 at 10:12, Dave Benjamin wrote:
> In article <mailman.106568533...@python.org>, gabor wrote:
> > as far as i know in python there aren't any private (i mean not accessible
> > from the outside of the object) methods/fields.
> >
> > why?
>
> No offense, but this is like the 4000th time someone has asked that question
> here. Could you try searching Google groups first?

you're right, i'm sorry.

after reading the archives:

i think i didn't express myself too well.
i'll try again:

i'm aware of the fact that you can declare a variable private with "__".
but i just don't like prefix-notation. i don't like the mMember or
lpszCommandLine style notation, and also the $variable style ones.

at least for me it seemed that adding a "private" keyword somewhere is
more elegant. but there isn't anything like that.

that's why it seems to me that the designers of the language don't
recommend you to use private variables at all, but if you want, you can
use this 'hack' ( i mean the "__" notation).


thanks,
gabor


Peter Hansen

unread,
Oct 9, 2003, 9:28:21 AM10/9/03
to
gabor wrote:
>
> On Thu, 2003-10-09 at 10:12, Dave Benjamin wrote:
> > In article <mailman.106568533...@python.org>, gabor wrote:
> > > as far as i know in python there aren't any private (i mean not accessible
> > > from the outside of the object) methods/fields.
> > >
> > > why?
> >
> > No offense, but this is like the 4000th time someone has asked that question
> > here. Could you try searching Google groups first?
>
> you're right, i'm sorry.
>
> after reading the archives:
>
> i think i didn't express myself too well.
> i'll try again:

Don't bother. You perhaps didn't really read enough of the archives,
because Dave's point still stands. None of your questions or comments,
as far as I can tell, ask or say anything that hasn't already been
asked (and answered) or said before.

In summary: it's more of a philosophical difference than anything, and
Python simply doesn't *want* a "private" keyword, nor things like that
which artificially restrict the programmer. (Again, even that comment
adds nothing new, so you're really wasting your and our time by responding
rather than continuing to read the zillion old threads on the topic.)

-Peter

Michael Chermside

unread,
Oct 9, 2003, 9:01:21 AM10/9/03
to
gabor writes:
> in java/c++ i can make a method private, this way unaccessible for the outside
> world. i think it helps a lot to make for example a library more robust.
>
> i know that there is some kind of notation to make a method/field private,
> but one can still overwrite it's value.
>
> what's the reason for this?
>
> i'l mostly interested in the design reasons.

First of all, I wonder WHY you think that it helps a lot to make (for
example) a library more robust. This is a serious question... because
it's not so obvious that it's true.

Suppose it's NOT true... suppose that having language-enforced access
limitations (as opposed to enforcing by convention) DOESN'T actually
make libraries more robust. Well, then, most of the time it would make
no difference whether your language had "private" declarations...
there would be a little more typing needed to use them, but the effort
might pay for itself in increased explicitness. HOWEVER, once in a
while, I have found that I have to use a library which doesn't quite
do what I want. Perhaps I have a slightly different use than the
original author had considered, or perhaps the original code is
buggy. In these rare cases, not having a language-enforced access
restrictions is USEFUL because I can work around the bug.

One design reason for NOT including language-enforced access
restrictions in Python is (IMHO) to allow the programmer the freedom
to make this kind of change when she wants to (realizing that by doing
so she is foregoing all warranty and incurring the risk of breaking
the library). A second (probably more significant) reason is because
NOT having it makes the object model quite simple... notice how in
Java and C++ make distinctions between methods and attributes, between
calling something from within the same class or file and calling it
from "outside". They require the invention of "friend" or "package"
access -- lots of complication needed just to support language-
enforced access restrictions. And balanced against these is the
increased library robustness that you (and others... you are not
alone!) say comes with the private declarations.

So you can see, this question of whether the increased robustness is
real is a VERY important question. Here's my take on the matter
(see also http://byandlarge.net/scuttlebutt/archives/000042.html):

There are two reasons that "true" (language-enforced, not
convention-enforced) privacy might be useful:

(1) Mistake prevention -- avoiding accidental manipulation of
bits intended for internal use only.
(2) Enforcing coding standards -- for example, libraries should
only be accessed via certain access points.
(3) Preventing API publication -- so you can release a library
but later change some internals without breaking any
user's programs.
(4) Security -- protecting from coders with malicious intent.

All of these are valid reasons for wanting to distinguish between
private and public interfaces. But if you take a "we're all grownups
here" attitude toward your fellow programmers (as Python does),
then a simple convention (like leading-underscore-means-private)
will suffice for cases (1), (2) and (3). Sure, a few programmers will
decide to mangle your library's internals, but they do so at their
own risk!

Reason (4), on the other hand, can never be satisfied by a convention.
On the other hand, it is ALSO not satisfied by lots of existing
languages, and they manage to get along just fine! C++, for instance,
has several work-arounds that a malicious coder could use (the
simplest being to use "#define private public" before importing a
header file). As a result, the language CANNOT provide security
guarantees for running untrustworthy code. (Java or C# are much better
in this regard... they offer a feature that Python simply lacks.)

Of course, it might be that people are so lax about following
conventions that they're simply not very helpful. Perhaps in REAL life,
people just code willy-nilly and ignore any conventions not enforced
by the compiler. I've even seen shops which were like that. But it is
my experience that very few programmers behave this way, and that those
that do tend to have a net negative effect on projects. I've never
had a problem with a library because it didn't enforce access strictly
enough. I HAVE had cases where a library enforced access TOO strictly
(particularly trying to call const-aware C++ librarys from non-const-
using C++ code). I have also broken libraries by mis-using them, but
in such cases I had only myself to blame. And I've also SAVED libraries
by "misusing" or patching them in some manner.

What is YOUR experience on the matter? Can anyone here recount a time
when they had a problem with a library (or other code) in any language
because it DIDN'T enforce access strictly enough?

-- Michael Chermside

Harri Pesonen

unread,
Oct 10, 2003, 3:16:36 PM10/10/03
to
Peter Hansen wrote:
> gabor wrote:
>
>>On Thu, 2003-10-09 at 10:12, Dave Benjamin wrote:
>>
>>>In article <mailman.106568533...@python.org>, gabor wrote:
>>>
>>>>as far as i know in python there aren't any private (i mean not accessible
>>>>from the outside of the object) methods/fields.
>>>>
>>>>why?
>>>
>>>No offense, but this is like the 4000th time someone has asked that question
>>>here. Could you try searching Google groups first?
>>
>>you're right, i'm sorry.
>>
>>after reading the archives:
>>
>>i think i didn't express myself too well.
>>i'll try again:
>
> Don't bother. You perhaps didn't really read enough of the archives,
> because Dave's point still stands. None of your questions or comments,
> as far as I can tell, ask or say anything that hasn't already been
> asked (and answered) or said before.

Because it has been asked 4000 times probably means that there is a
great need for the feature...

> In summary: it's more of a philosophical difference than anything, and
> Python simply doesn't *want* a "private" keyword, nor things like that
> which artificially restrict the programmer. (Again, even that comment
> adds nothing new, so you're really wasting your and our time by responding
> rather than continuing to read the zillion old threads on the topic.)

"Python" doesn't want a "private" keyword? I have quite a limited Python
experience but I would like to have the following features in Python
that are common in other languages:

* Option Explicit
* variable type declaration (optional)
* private variables/methods

Most of these are handy for large projects, where you want to be sure
that a class is not misused (by other developers). These also mean that
it is much harder to create bugs. I like Python a lot, but with these
features it would be much better for serious development of complex
applications, not just for scripting.

One thing I have noticed that the keyword "global" is very confusing.
For example, the following is syntactically valid Python:

a = 1
def b():
a = 2
def c():
return a

But it does not work as expected. Function b just creates a new local
variable "a" inside function b! The correct function is of course:

def b():
global a
a = 2

On the other hand, function c refers to the same global variable just
fine without any extra "global" keyword. Why on earth?? :-) In every
other language I know you don't need "global". It is ugly.

Harri

Alex Martelli

unread,
Oct 10, 2003, 6:22:04 PM10/10/03
to
Harri Pesonen wrote:
...

> Because it has been asked 4000 times probably means that there is a
> great need for the feature...

I can't think of ANY "feechur" from other popular languages that hasn't
been asked for, thousands of times. Does this mean that "there is a
great need" for each and all of them? Not at all: it just means that people
hanker for what they're familiar with. If Python were to satisfy even
1/10th of this incessant barrage of requests, it would devolve to a
large amorphous blob -- like many other languages have. The people
requesting these features are typically NOT experienced with Python:
they haven't experienced how the LACK of these features in fact makes
it easier and more productive to write application programs.


> "Python" doesn't want a "private" keyword?

If Python can be said to have a will -- embodied in Guido or spread
as community consensus -- it definitely doesn't.

> I have quite a limited Python
> experience but I would like to have the following features in Python
> that are common in other languages:

Not 'but', but rather, THEREFORE. Reread your words with this
change and with some luck you may get it.


> * Option Explicit
> * variable type declaration (optional)
> * private variables/methods
>
> Most of these are handy for large projects, where you want to be sure
> that a class is not misused (by other developers). These also mean that
> it is much harder to create bugs. I like Python a lot, but with these
> features it would be much better for serious development of complex
> applications, not just for scripting.

You are wrong. I used to harbor similar illusions (to a lesser degree,
because I _did_ have SOME experience with other dynamic languages,
but not in using them for really large apps) back when the language I
most used was C++. I was wrong, too.

Other developers aren't any likelier to "misuse" your class than you
are to misdesign it in the first place -- and you'll NEVER "be sure"
anyway, as restrictions can be worked around. _ADVISORY_
indications of "privacy" -- the convention of starting the name with
a single underscore -- are much simpler and equally effective for
your purposes. Python is wonderfully effective for programming
large applications, exactly as it is today.


> One thing I have noticed that the keyword "global" is very confusing.

You are right. It would be better if the current module could be
imported -- by using some reserved special module name in a
perfectly ordinary 'import' instruction -- so that global variables
could then be re-bound as attributes of this module.

Just to give you an idea, in today's Python you could add this
feature as:

# part to be executed once, e.g. in site.py
import __builtin__, sys
_base_import = __builtin__.__import__
def __import__(name, *args):
if name == '__current_module__':
name = sys._getframe(1).f_globals['__name__']
return _base_import(name, *args)
__builtin__.__import__ = __import__
# end of part to be executed once

# example use
x = 23

def set_the_global():
import __current_module__
__current_module__.x = 45

print x
set_the_global()
print x


emits
23
45

> For example, the following is syntactically valid Python:
>
> a = 1
> def b():
> a = 2
> def c():
> return a
>
> But it does not work as expected. Function b just creates a new local
> variable "a" inside function b! The correct function is of course:
>
> def b():
> global a
> a = 2
>
> On the other hand, function c refers to the same global variable just
> fine without any extra "global" keyword. Why on earth?? :-) In every

Because reading is different from writing. Reading globals is (more or
less) all right; writing globals is a delicate decision that is well worth
emphasizing. So, anything that's written (any name that's re-bound,
to be precise) is deemed to be local -- unless explicitly mentioned in
a global statement.

The problem with global is that it's not clear enough. If there simply
was NO way at all to have any assignment to a bare name, such
as "a=2", EVER affect anything BUT a local, things would be much
clearer; the need to import __current_module__ would emphasize what
a serious, think-twice-about-it decision it is to choose to rebind
module-global names. It would also emphasize that 'global' means
'of this module', not in any way of ALL modules -- a misconception
that often affects newbies.

Hmmm -- maybe THIS is worth proposing for 2.4 (with a
pending deprecation warning for the global statement)...

> other language I know you don't need "global". It is ugly.

Problem is, it's not quite ugly enough (nor quite clear enough).
Discouraging you from affecting globals is a swell idea, but I
think the 'global' statement may not be enough for that, whence
my newly conceived suggestion about importing...


Alex

Scott David Daniels

unread,
Oct 10, 2003, 8:09:15 PM10/10/03
to
Alex Martelli wrote:
> ...
> I can't think of ANY "feechur" from other popular languages that hasn't
> been asked for, thousands of times....
Aha! caught the Martellibot in a rare memory failure (perhaps a rare
double-bit parity error)? To my knowledge, nobody has suggested the
autodeclaration of variables which begin with the letters 'I' through
'N' as integer variables. So there. :-)

Now watch, he'll document 1003 requests on alt.lang.python.it.

-Scott David Daniels
Scott....@Acm.Org

Jordan Krushen

unread,
Oct 11, 2003, 1:12:31 AM10/11/03
to
On Fri, 10 Oct 2003 22:22:04 GMT, Alex Martelli <ale...@yahoo.com> wrote:

> The problem with global is that it's not clear enough. If there simply
> was NO way at all to have any assignment to a bare name, such
> as "a=2", EVER affect anything BUT a local, things would be much
> clearer; the need to import __current_module__ would emphasize what
> a serious, think-twice-about-it decision it is to choose to rebind
> module-global names. It would also emphasize that 'global' means
> 'of this module', not in any way of ALL modules -- a misconception
> that often affects newbies.

> Hmmm -- maybe THIS is worth proposing for 2.4 (with a
> pending deprecation warning for the global statement)...

I'm rather amused at the thought of a module importing itself. I find it
cleaner than global, and it also emphasizes that modules are singletons,
if you think about how a module *can* import itself.

I think that __current_module__ is perhaps a bit too lengthy (although I
appreciate the motivation behind this), but aside from that, I like it.

I'm also pleased with the ouroboros-like imagery it conjures..

J.

Alex Martelli

unread,
Oct 11, 2003, 11:46:10 AM10/11/03
to
Scott David Daniels wrote:

> Alex Martelli wrote:
>> ...
>> I can't think of ANY "feechur" from other popular languages that hasn't
>> been asked for, thousands of times....
> Aha! caught the Martellibot in a rare memory failure (perhaps a rare
> double-bit parity error)? To my knowledge, nobody has suggested the
> autodeclaration of variables which begin with the letters 'I' through
> 'N' as integer variables. So there. :-)

Darn. I should have added a word -- a "current" or "currently" somewhere.
Arithmetic IF, variable types based on initial letter of the name, and
other such features are not in the _currently_ popular versions of Fortran
(and I'm sure we can find early-60, now-deplored feechurs of Cobol or
RPG that are also rarely or never asked for).


> Now watch, he'll document 1003 requests on alt.lang.python.it.

that's it.comp.lang.python -- and I don't think I've met many old Fortran-IV
hands there...


Alex

Nick Vargish

unread,
Oct 11, 2003, 11:50:26 PM10/11/03
to
Scott David Daniels <Scott....@Acm.Org> writes:

> Aha! caught the Martellibot in a rare memory failure (perhaps a rare
> double-bit parity error)? To my knowledge, nobody has suggested the
> autodeclaration of variables which begin with the letters 'I' through
> 'N' as integer variables. So there. :-)

I think two key phrases were "popular language" and "feature".

Nick

--
# sigmask || 0.2 || 20030107 || public domain || feed this to a python
print reduce(lambda x,y:x+chr(ord(y)-1),' Ojdl!Wbshjti!=obwAcboefstobudi/psh?')

Terry Reedy

unread,
Oct 12, 2003, 1:42:10 AM10/12/03
to

"Jordan Krushen" <jor...@krushen.com> wrote in message
news:oprwu4uvju5ctagx@shawnews...

> I'm rather amused at the thought of a module importing itself. I
find it
> cleaner than global, and it also emphasizes that modules are
singletons,
> if you think about how a module *can* import itself.

You can already do this in the main module:

>>> __main__
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name '__main__' is not defined
>>> __name__
'__main__'
>>> import __main__
>>> __main__
<module '__main__' (built-in)>
>>> a=3
>>> __main__.__dict__['a']
3
>>> __main__.__dict__['b'] = 5
>>> b
5

>>> del __main__
>>> __main__
NameError: name '__main__' is not defined
>>> globals()[__name__] = __import__(__name__)
>>> __main__
<module '__main__' (built-in)>

I believe globals line above will work in imported modules, in which
__name__ is import name (file name if from file), but have not tested
it in such.

> I think that __current_module__ is perhaps a bit too lengthy

and redundant ;-)

Terry J. Reedy


Alex Martelli

unread,
Oct 12, 2003, 11:30:48 AM10/12/03
to
Terry Reedy wrote:
...

>>>> globals()[__name__] = __import__(__name__)
>>>> __main__
> <module '__main__' (built-in)>
>
> I believe globals line above will work in imported modules, in which
> __name__ is import name (file name if from file), but have not tested
> it in such.

Yes, this will work at the global level in any module. But it's not a
normal import instruction, while the modified builtin __import__ I
showed does allow normal importing; and your _use_ of __import__ and
globals() cannot bind a _local_ variable of a function to the current
module object.


>> I think that __current_module__ is perhaps a bit too lengthy
>
> and redundant ;-)

I disagree. Lengthy it may be, but we do want a 'reserved module
name' to use for this purpose. For a normal import instruction to
work, and to work just as well if you cut and paste the same function
elsewhere, I think we want to define that "import somespecificname" is
importing THIS module, the CURRENT module, under that name (or another
specified with 'as'). This can be experimented with easily, by changing
the builtin __import__ (or setting an import hook, maybe) in site-specific
file; and if it catches on the builtin __import__ could easily be customized
to perform the same task quite speedily.


Alex

Sean Ross

unread,
Oct 12, 2003, 1:36:41 PM10/12/03
to
"Alex Martelli" <ale...@yahoo.com> wrote in message
news:Iseib.204801$hE5.6...@news1.tin.it...

> >> I think that __current_module__ is perhaps a bit too lengthy
> >
> > and redundant ;-)
>
> I disagree. Lengthy it may be, but we do want a 'reserved module
> name' to use for this purpose. For a normal import instruction to
> work, and to work just as well if you cut and paste the same function
> elsewhere, I think we want to define that "import somespecificname" is
> importing THIS module, the CURRENT module, under that name (or another
> specified with 'as'). This can be experimented with easily, by changing
> the builtin __import__ (or setting an import hook, maybe) in site-specific
> file; and if it catches on the builtin __import__ could easily be
customized
> to perform the same task quite speedily.

Hi.
I'm not sure I'm clear on what behaviour "import __current_module__" is
expected to have.
There's a bit more to follow but I'll ask my main question up front so we're
clear:

"Which of the following behaviours is preferred?"

I've been playing with some code, using my own pet global workaround, and
I'm not sure
if it's accomplishing the correct behaviour. The results are certainly not
the same as yours.
in fact, I think the behaviour of my version may be unexpected and dangerous
...

If inside module A you import a function f() from another module B that
tries to use the
current module directly, rather than global, to set variables and you call
that function
(i.e., B.f()), my version will affect the values of A's global variables
whereas yours does
not. For example, here is some output from a test run of each method. The
code for all
of this will be posted at the bottom of this message. Note: I've added some
print statements
to your code.


# Output of running setglobal1.py using import __current_module__
setglobal1.x = 23
ENTERING setglobal1.set_the_global()
global x = 23
set __current_module__.x = 45
global x = 45
EXITING setglobal1.set_the_global()
ENTERING setglobal2.set_the_global()
global x = 57
set __current_module__.x = 88
global x = 88
EXITING setglobal2.set_the_global()
setglobal1.x = 45


# Output of running main1.py using import __main__
main1.x = 23
ENTERING main1.foo()
global x = 23
set main.x = 45
global x = 45
EXITING main1.foo()
ENTERING main2.foo()
global x = 57
main2.x = 45
set main.x = 88
global x = 57
EXITING main2.foo()
main1.x = 88


As you can see, setglobal1.x = 45 in your version, but my analogous
variable main1.x = 88.

Here's the code:

#==============================================
# site.py


import __builtin__, sys
_base_import = __builtin__.__import__
def __import__(name, *args):
if name == '__current_module__':
name = sys._getframe(1).f_globals['__name__']
return _base_import(name, *args)
__builtin__.__import__ = __import__
# end of part to be executed once

#===============================================
# setglobal1.py

import setglobal2
x = 23

def set_the_global():
print "ENTERING setglobal1.set_the_global()"
import __current_module__
global x
print "global x = %s"%x
__current_module__.x = 45
print "set __current_module__.x = %s"%__current_module__.x
print "global x = %s"%x
print "EXITING setglobal1.set_the_global()"

if __name__ == "__main__":
print "setglobal1.x = %s"%x
set_the_global()
setglobal2.set_the_global()
print "setglobal1.x = %s"%x


#===============================================
# setglobal2.py
x = 57

def set_the_global():
print "ENTERING setglobal2.set_the_global()"
import __current_module__
global x
print "global x = %s"%x
__current_module__.x = 88
print "set __current_module__.x = %s"%__current_module__.x
print "global x = %s"%x
print "EXITING setglobal2.set_the_global()"

if __name__ == "__main__":
print "setglobal2.x = %s"%x
set_the_global()
print "setglobal2.x = %s"%x


# And now my version:

#===============================================
# main1.py
import main2

x = 23

def foo():
print "ENTERING main1.foo()"
import __main__ as main
global x
print "global x = %s"%main.x
main.x = 45
print "set main.x = %s"%main.x
print "global x = %s"%x
print "EXITING main1.foo()"

if __name__ == "__main__":
print "main1.x = %s"%x
foo()
main2.foo()
print "main1.x = %s"%x

#===============================================
# main2.py
x = 57

def foo():
print "ENTERING main2.foo()"
import __main__ as main
global x
print "global x = %s"%x
print "main2.x = %s"%main.x
main.x = 88
print "set main.x = %s"%main.x
print "global x = %s"%x
print "EXITING main2.foo()"

if __name__ == "__main__":
print "main2.x = %s"%x
foo()
print "main2.x = %s"%x

Thanks for your time,
Sean


Terry Reedy

unread,
Oct 12, 2003, 1:49:54 PM10/12/03
to

"Alex Martelli" <ale...@yahoo.com> wrote in message
news:Iseib.204801$hE5.6...@news1.tin.it...
> Terry Reedy wrote:

> >> I think that __current_module__ is perhaps a bit too lengthy
> > and redundant ;-)

I was slightly wrong since __name__ allows but does not constitute a
binding of the module itself.

> I disagree. Lengthy it may be, but we do want a 'reserved module
> name' to use for this purpose.

I believe it would be easily possible to bind a module to
<module>.__self__ or <module>. __module__ at the same time
<module>__name__, .__file__, and .__doc__ are. ('Current' is no more
needed for __module__ than for the other vars.) If their were use
cases for self-access nearly as good as those for the others, and not
just the cuteness factor, I would support the addition. I would guess
that Guido and the other main developers either have not had such
needs or have not recognized such needs. Don't know if this addition
has been discussed before, and don't have time to search right now.

Terry J. Reedy

Alex Martelli

unread,
Oct 12, 2003, 6:01:38 PM10/12/03
to
Dennis Lee Bieber wrote:

> Alex Martelli fed this fish to the penguins on Saturday 11 October 2003
> 08:46 am:


>
>> Darn. I should have added a word -- a "current" or "currently"
>> somewhere. Arithmetic IF, variable types based on initial letter of
>> the name, and other such features are not in the _currently_ popular
>

> According to my text (FORTRAN 90/95 explained), the Arithmetic IF
> is
> still available in Fortran 90, though considered "obsolescent" (a
> phrase I would put on par with Python's "deprecated"). Implicit typing
> (I-N -> integer) is also still in Fortran 90, though discouraged (but

i.e., they're there, but are not currently popular -- something popular
would be praised, not called names;-).


Alex

Alex Martelli

unread,
Oct 12, 2003, 6:37:45 PM10/12/03
to
Terry Reedy wrote:
...

> I believe it would be easily possible to bind a module to
> <module>.__self__ or <module>. __module__ at the same time
> <module>__name__, .__file__, and .__doc__ are. ('Current' is no more

Yes, it would (a tiny patch to the C code).

> needed for __module__ than for the other vars.) If their were use
> cases for self-access nearly as good as those for the others, and not
> just the cuteness factor, I would support the addition. I would guess

My use case is: deprecating the global statement.


Alex

Alex Martelli

unread,
Oct 12, 2003, 6:42:12 PM10/12/03
to
Sean Ross wrote:
...

> Hi.
> I'm not sure I'm clear on what behaviour "import __current_module__" is
> expected to have.

Just like any other import, it binds the name to a module object -- except
that it specifically binds said name to the module containing the function
that executes this import statement. The use case is: deprecating the
global statement. Setting a global variable would instead use:
import __current_module__
__current_module__.thevariable = 23

So, your version does something very different from mine.


Alex

Christopher Koppler

unread,
Oct 13, 2003, 12:51:26 AM10/13/03
to
On Sun, 12 Oct 2003 22:42:12 GMT, Alex Martelli <ale...@yahoo.com>
wrote:

>Sean Ross wrote:


> ...
>> Hi.
>> I'm not sure I'm clear on what behaviour "import __current_module__" is
>> expected to have.
>
>Just like any other import, it binds the name to a module object -- except
>that it specifically binds said name to the module containing the function
>that executes this import statement. The use case is: deprecating the
>global statement. Setting a global variable would instead use:
> import __current_module__
> __current_module__.thevariable = 23
>

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

And every module would set it's __global__ to itself by default...


Just a naive idea, of course...

--
Christopher

Bengt Richter

unread,
Oct 13, 2003, 1:53:48 AM10/13/03
to
On Fri, 10 Oct 2003 22:22:04 GMT, Alex Martelli <ale...@yahoo.com> wrote:

>Harri Pesonen wrote:
> ...
[...]

Hm, since one way or another you have to tell the compiler you want to
rebind a global, I think maybe the situation could be normalized by
requiring the global name to pre-exist if it is to be rebound from within a function.
then we could change the 'global' keyword, and have a new one instead: 'external'

The idea is to generalize this to any names that are visible at compile time in eclosing scopes ;-)
I think requring pre-existence and visibility at compile time could make it work. Thus

g=123
def foo():
external: g
nested = 456
def bar():
external: nested
g = 'no effect on global 123, just local, only nested is external here'
nested = 789
bar() # nested becomes 789
g = nested # g becomes 789

I don't think it would be a good idea to waive the requirement for pre-existence and
visibility for where that currently works with 'global:' (i.e., defaulting to current
'global:' logic when the declared name is not visible) even though you could.
Best to avoid the kind of silent bugs that would come from misspelled names
in external declarations.

Only allowing 'external' inside a function would emphasize that it only reaches the
file global scope at most, not a universal global space. Requiring pre-existence would generate
errors if someone mistakenly thought they could rebind another module's global names
with an unqualified name by e.g. importing *, whose results wouldn't be visible at compile time.

My .02 ;-)

Regards,
Bengt Richter

Harri Pesonen

unread,
Oct 13, 2003, 4:18:12 PM10/13/03
to

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

How about the following:

def b():
global.a = 2
a = 3

Is the second "a" still global?

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.

Harri

Sean Ross

unread,
Oct 13, 2003, 5:01:05 PM10/13/03
to

"Harri Pesonen" <fue...@sci.fi> wrote in message
news:SMDib.231$8j...@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...

Sean


Harri Pesonen

unread,
Oct 13, 2003, 10:54:14 PM10/13/03
to
Sean Ross wrote:

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

Sean Ross

unread,
Oct 14, 2003, 12:39:38 AM10/14/03
to

"Harri Pesonen" <fue...@sci.fi> wrote in message
news:aAJib.269$8j....@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


Mel Wilson

unread,
Oct 14, 2003, 10:57:31 AM10/14/03
to
In article <Iseib.204801$hE5.6...@news1.tin.it>,
Alex Martelli <ale...@yahoo.com> wrote:

>Terry Reedy wrote:
>>> I think that __current_module__ is perhaps a bit too lengthy
>>
>> and redundant ;-)
>
>I disagree. Lengthy it may be, but we do want a 'reserved module
>name' to use for this purpose.

To me, the existence of a qualified

__current_module__.xyz = 3

implies that another local variable can also be called xyz.
So we're forced to code things like

__current_module__.xyz = 1 - __current_module__.xyz

even with all the beautification brackets '__', this starts
to look cumbersome to me. I would also prefer (while we're
talking about me) that '__' be a hint that we're dealing
with wizard code -- overloading standard operators inside
class definitions, etc. I don't think I should have to put
on my masked avenger tights just to get at my own
module-level variables.

Maybe Python 3 could re-cast the 'global' keyword to take
the place of '__current_module__'. 'module' might be more
meaningful, if it doesn't ultimately take one too many
useful names away from the programmers.

Regards. Mel.

Alex Martelli

unread,
Oct 14, 2003, 1:07:41 PM10/14/03
to
Mel Wilson wrote:

> In article <Iseib.204801$hE5.6...@news1.tin.it>,
> Alex Martelli <ale...@yahoo.com> wrote:
>>Terry Reedy wrote:
>>>> I think that __current_module__ is perhaps a bit too lengthy
>>>
>>> and redundant ;-)
>>
>>I disagree. Lengthy it may be, but we do want a 'reserved module
>>name' to use for this purpose.
>
> To me, the existence of a qualified
>
> __current_module__.xyz = 3
>
> implies that another local variable can also be called xyz.
> So we're forced to code things like
>
> __current_module__.xyz = 1 - __current_module__.xyz
>
> even with all the beautification brackets '__', this starts
> to look cumbersome to me. I would also prefer (while we're

you can of course use all normal possibilities of import, e.g:

import __current_module__ as g
g.xyz = 1 - g.xyz


> Maybe Python 3 could re-cast the 'global' keyword to take
> the place of '__current_module__'. 'module' might be more
> meaningful, if it doesn't ultimately take one too many
> useful names away from the programmers.

You can use any identifier you please after the 'as'.


Alex

Carlo v. Dango

unread,
Oct 16, 2003, 4:12:53 AM10/16/03
to
On 09 Oct 2003 14:06:06 +0200, gabor <ga...@z10n.net> wrote:

> On Thu, 2003-10-09 at 10:12, Dave Benjamin wrote:
>> In article <mailman.106568533...@python.org>, gabor
>> wrote:
>> > as far as i know in python there aren't any private (i mean not
>> accessible
>> > from the outside of the object) methods/fields.

do you want private or protected? private can be acomplished with the ugly
__ hack, but you can't create protected properties---this really suxx...


-carlo

--
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/

0 new messages