modules share variables without class def

Alex Martelli aleax at aleax.it
Mon Nov 4 04:43:23 EST 2002


<posted & mailed>

Ulrich Backes wrote:

> Hi there,
> 
> from several postings, i compiled the following scheme:
> 
> # test.py:
> from func import testf
> import globalvars
> globalvars.port = 1
> print testf() # -----> 1 OK!
> 
> # globalvars.py:
> port = None
> global port

This 'global port' statement is (innocuous but) useless.

A global statement in global scope is always useless.

The only real purpose of the global statement is to be
within a function that needs to RE-BIND a global name.



> # func.py:
> import globalvars
> def testf():
>   return(globalvars.port)

The parentheses in the return statement are (innocuous
but) useless.

I STRONGLY recommend you avoid including useless clutter
in your code, even when it's technically innocuous.  It
may make it harder to see the forest for the trees, and
in this sense be DAMAGING, *NOT* really innocuous.

William of Occam had it right: entities must not be
multiplied without necessity.  He'd have been a pretty
good Python programmer, I think.


> That works. But if i try to use the blank variable name, it fails:
> 
> # test.py:
> from func import testf
> from globalvars import port

This from/import statement binds to unqualified name 'port'
the value to which globalvars.port is also bound.
In this sense, it's like the sequence:

import globalvars
port = globalvars.port
del globalvars

> port = 1

This re-binds unqualified name 'port' to the value 1.

Re-binding a name *NEVER* affects other names bound to
the same value, of course.

Thus, in particular, after
    port = globalvars.port
or equivalently
    from globalvars import port

re-binding unqualified name port cannot possibly have
ANY effect on name globalvars.port.

> print testf() # -----> None...

Of course -- name globalvars.port was first bound
to value None, and never re-bound.  And even if it was:


> # globalvars.py:
> port = None
> global port

Again, a redundant global statement.

> 
> # func.py:
> from globalvars import port

this too binds unqualified name 'port' to whatever value
name 'globalvars.port' is bound at this time.  Now, even
if name globalvars.port were to be re-bound to different
values, this would have no conceivable effect whatsoever
on unqualified name 'port'.

> def testf():
>   return(port)

Again, redundant parentheses.

> 
> Thanks for your advice,

There seems to be some substantial misunderstandings about
what is a name, the binding of one or more names to a value,
and the effect (or, rather, utter lack of any) that re-binding
one of the several names currently bound to a value should
have on the other names that were bound to the same value.

Names are not "aware" of each other.  If any given object
has more than one name bound to it at a given time (it makes
NO difference whether the binding was performed via the
usual "assignment statement", or via other means such as
the from statement), you can rebind any one of those names
without ANY effect on the other names.

My practical advice is: forget Python has a 'from' statement.
It's intended as a handy shorthand, but I think it causes
confusion in newbies.  ANYTHING you can do with 'from', you
can do with 'import' too, possibly followed by binding or
re-binding with assignments and/or unbinding via the del
statement -- 'from' can be slightly handier and more concise,
but that tiny gain is not worth the confusion it can cause.
Whatever you just can't do with 'import', you can't do
with 'from' either.

One think you just can't do is "magically bind" unqualified
names in several modules so that a re-binding of one of those
names will magically cause re-bindings of some or all of the
others.  Unqualified names just don't work that way.  Give up.


Alex




More information about the Python-list mailing list