Re: Variables with cross-module usage

0 views
Skip to first unread message

MRAB

unread,
Nov 28, 2009, 5:36:24 PM11/28/09
to pytho...@python.org
Nitin Changlani. wrote:
> Hello everyone,
>
> I am fairly new to Python and occasionally run into problems that are
> almost always resolved by referring to this mailing-list's archives.
> However, I have this one issue which has got me stuck and I hope you
> will be tolerant enough to help em out with it!
>
> What I want to achieve is something like the global variables in C/C++:
> you declare them in one file and "extern" them in all the files where
> you need to use them. I have 3 files: one.py, two.py and three.py as below:
>
> one.py
> ----------
> a = 'place_a'
> b = 'place_b'
> x = 'place_x'
>
> myList = [a, b, 'place_c']
>
> ======================================================================
>
> two.py
> ----------
> import one
>
> def myFunc():
> print one.x
> print one.myList
>
> ======================================================================
>
> three.py
> ------------
> import one
> import two
>
> def argFunc():
> one.x = 'place_no_x'
> one.a = 'place_no_a'
> one.b = 'place_no_b'
>
> if __name__ == '__main__':
> two.myFunc()
> print
> argFunc()
> two.myFunc()
>
> ======================================================================
>
> Output:
> -----------
> 'place_x'
> ['place_a', 'place_b', 'place_c']
>
> 'place_no_x'
> ['place_a', 'place_b', 'place_c'] (*** instead of ['place_no_a',
> 'place_no_b', 'place_c'] ***)
>
> The last line in the output is what's baffling me. Can anyone please
> help me know if I am doing something wrong?
>
What's confusing you?

myList gets its value (['place_a', 'place_b', 'place_c']) when one.py is
first imported, and you never change it after that.

Rami Chowdhury

unread,
Nov 28, 2009, 5:46:37 PM11/28/09
to MRAB, pytho...@python.org
Hi Nitin,

On Sat, Nov 28, 2009 at 14:36, MRAB <pyt...@mrabarnett.plus.com> wrote:
> Nitin Changlani. wrote:
>> three.py
>> ------------
>> import one
>> import two
>>
>> def argFunc():
>>    one.x = 'place_no_x'
>>    one.a = 'place_no_a'
>>    one.b = 'place_no_b'
>>

I think this is what is biting you. You might expect that after
argFunc, one.x would be set to 'place_no_x' and so on. However,
Python's scoping doesn't work like that -- the name one.x is only
rebound in the function's scope, so outside of argFunc (e.g. in your
main printing code) one.x is still bound to 'place_x'.

HTH,
Rami

Matt Nordhoff

unread,
Nov 28, 2009, 5:57:09 PM11/28/09
to Rami Chowdhury, pytho...@python.org

Not true. argFunc does not rebind the name "one", it mutates the module
object referred to by the name "one". Since there is only one instance
of a given module*, the change is indeed reflected everywhere the "one"
module is accessed.

The problem is that argFunc does not modify (or replace) one.myList, as
MRAB said.

* Unless you do something strange like reload() or editing sys.modules
or having module available under different names...or something.
--
Matt Nordhoff

Rami Chowdhury

unread,
Nov 28, 2009, 6:06:11 PM11/28/09
to Matt Nordhoff, pytho...@python.org
--------
Rami Chowdhury
"Never assume malice when stupidity will suffice." -- Hanlon's Razor
408-597-7068 (US) / 07875-841-046 (UK) / 0189-245544 (BD)

On Sat, Nov 28, 2009 at 14:57, Matt Nordhoff <mnor...@mattnordhoff.com> wrote:
> Rami Chowdhury wrote:
>> Hi Nitin,
>>
>> On Sat, Nov 28, 2009 at 14:36, MRAB <pyt...@mrabarnett.plus.com> wrote:
>>> Nitin Changlani. wrote:
>>>> three.py
>>>> ------------
>>>> import one
>>>> import two
>>>>
>>>> def argFunc():
>>>>    one.x = 'place_no_x'
>>>>    one.a = 'place_no_a'
>>>>    one.b = 'place_no_b'
>>>>
>>
>> I think this is what is biting you. You might expect that after
>> argFunc, one.x would be set to 'place_no_x' and so on. However,
>> Python's scoping doesn't work like that -- the name one.x is only
>> rebound in the function's scope, so outside of argFunc (e.g. in your
>> main printing code) one.x is still bound to 'place_x'.
>>
>> HTH,
>> Rami
>
> Not true. argFunc does not rebind the name "one", it mutates the module
> object referred to by the name "one". Since there is only one instance
> of a given module*, the change is indeed reflected everywhere the "one"
> module is accessed.

Ah, thanks for clarifying!

Mel

unread,
Nov 28, 2009, 6:26:25 PM11/28/09
to
Rami Chowdhury wrote:

No, It's not like that. MRAB had it. The thing is, that when one.py is
imported, it sets the name one.a to refer to a string 'place_a'. Then a
list named one.myList is built with one.myList[0] referring to the same
string as one.a . So far, so good.

Then the function argFunc is called. It uses `one` as a name from its
global namespace. Inside argFunc, the names one.x and one.a are rebound to
different strings from the ones they started with. *But* one.myList[0]
isn't touched, and still refers to 'place_x' like it always did.

Mel.


Nitin Changlani

unread,
Nov 28, 2009, 10:18:11 PM11/28/09
to pytho...@python.org
Thanks for the reply MRAB, Rami, Matt and Mel,

I was assuming that since one.myList0] = one.a, the change in one.a will
ultimately trickle down to myList[0] whenever myList[0] is printed or used
in an expression. It doesn't come intuitively to me as to why that should
not happen. Can you kindly suggest what is the correct way to go about it?

Nitin.

Message has been deleted

Steven D'Aprano

unread,
Nov 29, 2009, 1:02:41 AM11/29/09
to


You are confusing *names* and *objects*. The presence or absence of a
module qualifier is irrelevant, so for simplicity I will avoid it. I will
use ` ` quotation marks to refer to names, to avoid confusing them with
strings.


The Python statement

a = "some text"

creates a name `a` which is bound to the object "some text".

myList[0] = a

stores the object bound to the name `a` to the first position of myList,
not the name itself. So myList[0] ends up being "some text", but it has
no idea whether it came from the name `a` or somewhere else.

Then when you execute:

a = "different text"

the name `a` is bound to the object "different text". But this doesn't
affect myList[0] at all, because you're not changing the object "some
text" -- strings are immutable and can't be changed.

--
Steven

Terry Reedy

unread,
Nov 29, 2009, 8:00:07 PM11/29/09
to pytho...@python.org
Dennis Lee Bieber wrote:

> In these languages, the names always refer to the same location.
> Python confuses matters by having names that don't really refer to
> location, but are attached to the objects.

In everyday life and natural languages, names refer to people, other
objects, roles, and only occasionally to places that can be occupied. I
could claim that it is classical computer languages that confuse by
restricting names to locations in a linear sequence. You are just used
to the straightjacket ;-).

Lie Ryan

unread,
Nov 30, 2009, 12:10:23 AM11/30/09
to

In everyday life and natural languages, though an object may have many
names/aliases; once objects are assigned a name, it is practically
impossible to change the name to the object the name will be practically
stuck to it forever. In everyday life and natural languages, a single
name can be used to refer to multiple objects just by context without
referring any namespace. Let's not start making analogism between nature
and silicon.

And of all, no one is confused. It is just a matter of assigning new
shade of meaning to a word.

Terry Reedy

unread,
Nov 30, 2009, 3:51:02 PM11/30/09
to pytho...@python.org
Lie Ryan wrote:
> On 11/30/2009 12:00 PM, Terry Reedy wrote:
>> Dennis Lee Bieber wrote:
>>
>>> In these languages, the names always refer to the same location.
>>> Python confuses matters by having names that don't really refer to
>>> location, but are attached to the objects.
>>
>> In everyday life and natural languages, names refer to people, other
>> objects, roles, and only occasionally to places that can be occupied. I
>> could claim that it is classical computer languages that confuse by
>> restricting names to locations in a linear sequence. You are just used
>> to the straightjacket ;-).
>
> In everyday life and natural languages, though an object may have many
> names/aliases; once objects are assigned a name, it is practically
> impossible to change the name to the object the name will be practically
> stuck to it forever.

When children play tag, the role of It is rebound to another child every
few seconds. When adults play conference, the role of Speaker or
Presenter is rebound to another person a few times per hour.

In Python, it easy, perhaps too easy, to rebind built-in names, but it
is usually a mistake. (Just yesterday there was a newbie post with that
mistake.) It is common for global names to be bound just once
(especially to functions and classes).

In both human life and programming performed by humans, the time scale
of name rebinding varies tremendously. Not surprising really.

> In everyday life and natural languages, a single
> name can be used to refer to multiple objects just by context without
> referring any namespace.

Namespace are contexts. They were (re)invented in programming just to
make it easier to have single name could refer to different objects --
in different contexts. Names bound within a function are interpreted as
being within the default local context without explicitly referring to
it. Indeed, one cannot explicitly refer to the local namespace of
functions, only to a dict copy thereof.

> Let's not start making analogism between nature and silicon.

There are several things wrong with this.

You meant 'analogies'.

I will make them when I want to, which is when I think they are useful
in providing new viewpoints and insight. They are one way to break out
of straight-jacketed or boxed thinking. If you prefer your box, ignore me.

Silicon is a part of the natural world, and I was not making any such
analogy. Python is an information processing and algorithm language, not
a silicon programming language per se. And indeed, without a concept of
'address', it is not very suited to that.

I *was* making an analogy between how we communicate informally about
the natural and social worlds and how we communicate more formally about
the abstract information world. Is it really surprising that we use the
same psychological mechanisms? Silicon machine languages do not have
names. And names, as used by humans, *are* the subject of discussion here.

Dennis clained that Python is confusing because it is not restricted to
naming locations. I said I could claim instead that it is the
restriction is confusing.

I did not go into that counterclaim, but indeed, many people who program
in C, for instance, use C names as if they were object names instead of
location names (or location,increment tuple names). Sometimes they even
forget that they are really just location names. One too-common result
of that confusion has been buffer overruns and virus programs that
exploit them. These are impossible in Python.

To me, the virtue of Python is that it allows one to think and write in
a relatively natural named-object model. Let the silicon-based
interpreter then translate that to a named-sequential-location model,
while avoiding the dangers thereof, even though it has the cost of
slower execution.

Terry Jan Reedy

Lie Ryan

unread,
Dec 1, 2009, 12:01:21 AM12/1/09
to
On 12/1/2009 7:51 AM, Terry Reedy wrote:
>> In everyday life and natural languages, a single name can be used to
>> refer to multiple objects just by context without referring any
>> namespace.
>
> Namespace are contexts. They were (re)invented in programming just to
> make it easier to have single name could refer to different objects --
> in different contexts. Names bound within a function are interpreted as
> being within the default local context without explicitly referring to
> it. Indeed, one cannot explicitly refer to the local namespace of
> functions, only to a dict copy thereof.

Let's stop with the silly analogies.

> > Let's not start making analogism between nature and silicon.
>
> There are several things wrong with this.
>
> You meant 'analogies'.

No, I meant "analogism". My spellchecker lined that red, but I know what
I meant. Let me define this word, which apparently is not (at least yet)
in the dictionary:
- analogism: the way of thinking that analogy must be perfectly similar
to the "real thing" in every single way, to the point of making grand
and complex story that is even more complicated than the "real thing"
itself.

> I did not go into that counterclaim, but indeed, many people who program
> in C, for instance, use C names as if they were object names instead of
> location names (or location,increment tuple names). Sometimes they even
> forget that they are really just location names. One too-common result
> of that confusion has been buffer overruns and virus programs that
> exploit them. These are impossible in Python.

"address names" and "object names", those are a good definition; stop at
that. Any more layers of analogies, with boxes, with strings, with how
human uses "name" in social life, or with how snakes align themselves
with stars are much less useful than just learning how the "name" itself
behave.

Let's stop teaching with excessive analogies, they just provide layers
and layers of thinking that would confuse people when the analogy
doesn't match the "real thing". Just learn how they behave, directly.

Analogy are fine to describe when first explaining how roughly something
works, but don't expect things to be the same down to the details; and
worse, don't make more analogies to cover up for the points the previous
analogy doesn't cover.

Just stop the "analogism" [1]!

[1] there I used the word again.

Reply all
Reply to author
Forward
0 new messages