Jach Feng wrote:
Mark Bourne 在 2022年8月29日 星期一下午6:40:59 [UTC+8] 的信中寫道:
Jach Feng wrote:
Chris Angelico 在 2022年8月29日 星期一下午1:58:58 [UTC+8] 的信中寫道:
On Mon, 29 Aug 2022 at 15:54, Jach Feng <jf...@ms4.hinet.net> wrote:

Richard Damon 在 2022年8月29日 星期一上午10:47:08 [UTC+8] 的信中寫道:
On 8/27/22 7:42 AM, Mark Bourne wrote:
Jach Feng wrote:
I have two files: test.py and test2.py
--test.py--
x = 2
def foo():
print(x)
foo()

x = 3
foo()

--test2.py--
from test import *
x = 4
foo()

-----
Run test.py under Winows8.1, I get the expected result:
e:\MyDocument>py test.py
2
3

But when run test2.py, the result is not my expected 2,3,4:-(
e:\MyDocument>py test2.py
2
3
3

What to do?

`from test import *` does not link the names in `test2` to those in
`test`. It just binds objects bound to names in `test` to the same
names in `test2`. A bit like doing:

import test
x = test.x
foo = test.foo
del test

Subsequently assigning a different object to `x` in one module does
not affect the object assigned to `x` in the other module. So `x = 4`
in `test2.py` does not affect the object assigned to `x` in `test.py`
- that's still `3`. If you want to do that, you need to import `test`
and assign to `test.x`, for example:

import test
test.x = 4
test.foo()

Yes, fundamental issue is that the statement

from x import y

makes a binding in this module to the object CURRECTLY bound to x.y to
the name y, but if x.y gets rebound, this module does not track the changes.

You can mutate the object x.y and see the changes, but not rebind it.

If you need to see rebindings, you can't use the "from x import y" form,
or at a minimum do it as:


import x

from x import y

then later to get rebindings to x.y do a

y = x.y

to rebind to the current x.y object.

--
Richard Damon
Yes, an extra "import x" will solve my problem too! Sometimes I am wondering why 
"from x import y" hides x? hum...can't figure out the reason:-)

"from x import y" doesn't hide x - it just grabs y. Python does what
you tell it to. :)

ChrisA
But I had heard people say that "from x import y" did import the whole x module into memory, just 
as "import x" did, not "grabs y" only. Is this correct?
`from x import y` does import the whole module x into memory, and adds
it to `sys.modules`. But it only binds the name `y` in the namespace of
module doing the import (and it binds it to the value of `x.y` at the
time the import is done - it doesn't magically keep them in sync if one
or the other is later reassigned).

The point about the whole module being imported is that you don't save
any memory by using `from x import y` to avoid importing some very large
object `z` from `x`. Those other large objects might be needed by
functions which have been imported (e.g. your `foo` function still needs
`x` even if you haven't imported `x` - so it still needs to be loaded
into memory) or might be imported and used by other modules importing
`x`, so they still have to be loaded when any part of `x` is imported -
they just don't have to be bound to names in the importing module's
namespace.

As Richard mentioned, if `x.y` is a mutable object (such as a list) you
can still mutate that object (e.g. add/remove items) and those changes
will be seen in both modules. That's because both are still bound to
the same object and you're mutating that existing object. If you assign
a new list to either, that won't be seen by the other.

--
Mark.
When using dot notation to change variable, no matter if 'x.y' is a mutable or 
immutable object, the change
will be seen in both modules except those early bindings.

--Jach

Yes, sorry, I'd used `x.y` as a way of referring to the variable `y` in module `x` as opposed to `y` in the current module. It doesn't help that I added the second paragraph and didn't notice that the third was then out of context.

If you use `import x` and assign to `x.y`, that will as you say be seen in both modules. On the other hand, if you use `from x import y`, then (as has been discussed) assigning to `y` in the module which has the import won't affect the value seen in module `x`. However, if `y` is mutable (e.g. a list), and no new object is assigned to it, then `y` still points to the same object in both modules, so mutating that existing object (e.g. `y.append(123)`) *will* affect what's seen in both modules - they're both referencing the same object, and you've modified that object, as opposed to assigning a new object to `y` in one of the modules.

--
Mark.
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to