private variables/methods

Bengt Richter bokr at oz.net
Mon Oct 13 01:53:48 EDT 2003


On Fri, 10 Oct 2003 22:22:04 GMT, Alex Martelli <aleaxit at 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




More information about the Python-list mailing list