473,397 Members | 1,969 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,397 software developers and data experts.

private variables/methods

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"

Jul 18 '05 #1
27 3773
In article <ma*********************************@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 :
Jul 18 '05 #2
On Thu, 2003-10-09 at 10:12, Dave Benjamin wrote:
In article <ma*********************************@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
Jul 18 '05 #3
gabor wrote:

On Thu, 2003-10-09 at 10:12, Dave Benjamin wrote:
In article <ma*********************************@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
Jul 18 '05 #4
Peter Hansen wrote:
gabor wrote:
On Thu, 2003-10-09 at 10:12, Dave Benjamin wrote:
In article <ma*********************************@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

Jul 18 '05 #5
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

Jul 18 '05 #6
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
Sc***********@Acm.Org

Jul 18 '05 #7
On Fri, 10 Oct 2003 22:22:04 GMT, Alex Martelli <al*****@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.
Jul 18 '05 #8
Harri Pesonen fed this fish to the penguins on Friday 10 October 2003
12:16 pm:


Because it has been asked 4000 times probably means that there is a
great need for the feature...
Or it just means that there are 4000 undisciplined programmers out
there who can't trust their own coding and require the language to
protect them from themselves.

For them, I suggest coding in Ada...

"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
Only found in M$ Basic dialects as I recall. Real BASIC only required
declarations for arrays (needed the size), and used special suffix
characters for type identification.
* variable type declaration (optional)
Well, if you posit an option explicit statement, being required to
declare variables would become an option...
* private variables/methods

Why? You don't trust yourself to stay away from "internal" details
when using a class?

Let's see... Languages that don't require variable declarations:

BASIC (though it does allow suffix character to differentiate number
from string)
FORTRAN (though it uses variables beginning I-N as integers, all others
are real)
Python (no restriction, any variable can refer to any type of object)
REXX (no restriction that I know of)
DCL (and most command line scripting languages)
APL
LISP (at least, the versions up to the early 80s)
FORTH

Languages that require declarations for all variables:

Ada
COBOL
C++
Java
assembly (well, you have to declare the storage space at least)

-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Bestiaria Home Page: http://www.beastie.dm.net/ <
Home Page: http://www.dm.net/~wulfraed/ <


Jul 18 '05 #9
Scott David Daniels fed this fish to the penguins on Friday 10 October
2003 17:09 pm:

Now watch, he'll document 1003 requests on alt.lang.python.it.
No... What he'll find are requests that variables beginning A-H and
O-Z be floats....

-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Bestiaria Home Page: http://www.beastie.dm.net/ <
Home Page: http://www.dm.net/~wulfraed/ <


Jul 18 '05 #10
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

Jul 18 '05 #11
Scott David Daniels <Sc***********@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?')
Jul 18 '05 #12

"Jordan Krushen" <jo****@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
Jul 18 '05 #13
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

Jul 18 '05 #14
"Alex Martelli" <al*****@yahoo.com> wrote in message
news:Is**********************@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
Jul 18 '05 #15

"Alex Martelli" <al*****@yahoo.com> wrote in message
news:Is**********************@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

Jul 18 '05 #16
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
one could say that of FORTRAN 77 too, and there is an awful lot of F77
code still being maintained (I should know, that's what I spent the
last 20 years doing!) by various defense contractors (and some was
developed new in the last decade even -- F90 had not made any in-roads
to the department I used to work for up to the time of my lay-off last
year).

Among the obsolescent features in F90: do loop with reals (removed in
F95), the above mentioned if, and the assigned goto (removed in F95 --
which would have required a major rewrite of one application I spent
years maintaining; it had been created as the /output/ from a
preprocessor that used a C-like syntax... local subroutines [with
global variables a la old BASIC] were handled by using assigned goto
for the return statements), alternate return labels, pause (removed in
F95), and Hollerith "H" edit descriptor (removed in F95).
-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Bestiaria Home Page: http://www.beastie.dm.net/ <
Home Page: http://www.dm.net/~wulfraed/ <


Jul 18 '05 #17
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

Jul 18 '05 #18
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

Jul 18 '05 #19
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

Jul 18 '05 #20
On Sun, 12 Oct 2003 22:42:12 GMT, Alex Martelli <al*****@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
Jul 18 '05 #21
On Fri, 10 Oct 2003 22:22:04 GMT, Alex Martelli <al*****@yahoo.com> wrote:
Harri Pesonen wrote:
...

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

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
Jul 18 '05 #22
Alex Martelli fed this fish to the penguins on Sunday 12 October 2003
15:01 pm:


i.e., they're there, but are not currently popular -- something
popular would be praised, not called names;-).
Depends on who's doing the coding <G> (I'll have to confess that I do
take advantage of the implicit integer range when coding do loops...
having to declare I,J,K, IX, JINX, or LYNX <G> at the top of a long
file just because they are used in a 10 line loop is a pain...

-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Bestiaria Home Page: http://www.beastie.dm.net/ <
Home Page: http://www.dm.net/~wulfraed/ <


Jul 18 '05 #23
Christopher Koppler wrote:
On Sun, 12 Oct 2003 22:42:12 GMT, Alex Martelli <al*****@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...


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

Jul 18 '05 #24

"Harri Pesonen" <fu****@sci.fi> wrote in message
news:SM************@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
Jul 18 '05 #25
Sean Ross wrote:
"Harri Pesonen" <fu****@sci.fi> wrote in message
news:SM************@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

Jul 18 '05 #26

"Harri Pesonen" <fu****@sci.fi> wrote in message
news:aA**************@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
Jul 18 '05 #27
Mel Wilson wrote:
In article <Is**********************@news1.tin.it>,
Alex Martelli <al*****@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

Jul 18 '05 #28

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Rajesh Garg | last post by:
Can we have private constructors and destructors? IF yes what is the use of such constructors or destructors.....in the sense where can these be implemented in a system................. I have...
1
by: Edward | last post by:
I have trouble with some of the concepts of OOP, and am struggling currently with Private Shared Functions. I think I understand Private (not available outside the class). I think I understand...
6
by: David Whitchurch-Bennett | last post by:
Hi There, I have created a very simple web user control, containing only a combo box. I have created a class which contains some private object variables, for example... Private _anObject as...
86
by: jopperdepopper | last post by:
Hi, finally giving php 5 a go, and going over the new approach to classes. Can someone clarify the public, private and protected to me? I quote the php manual: "The visibility of a property or...
63
by: time.swift | last post by:
Coming from a C++ / C# background, the lack of emphasis on private data seems weird to me. I've often found wrapping private data useful to prevent bugs and enforce error checking.. It appears...
7
by: Ray | last post by:
Hello, What do you think about emulating private variables for a class this way? function Something() { var private; Something.prototype.getPrivate = function() { return private; }...
8
by: David Veeneman | last post by:
Should a member variable be passed to a private method in the same class as a method argument, or should the method simply call the member variable? For years, I have passed member variables to...
13
by: PragueExpat | last post by:
I (think) that I've come up with a pattern that I haven't seen in any publications so far and I would like some feedback. Basically, I was looking for a way to inherit private functions and I came...
14
by: Karsten Dambekalns | last post by:
Hi. Thomas Mlynarczyk wrote: Why do you want them to be private in the first place? I have yet to see code where this really makes sense... And if it does, then the external public API is...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.