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?
import testYes, you are right. But because of I am using "from test import *" which makes the name "test" disappear in the test2 scope, so this is not work.
test.x = 4
test.foo()
--
Mark.
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()
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 xYes, 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
then later to get rebindings to x.y do a
y = x.y
to rebind to the current x.y object.
--
Richard Damon
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.
--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:-)
Richard Damon
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:
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?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.
--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:-)
Richard Damon
"from x import y" doesn't hide x - it just grabs y. Python does what
you tell it to. :)
ChrisA
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: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" doesn't hide x - it just grabs y. Python does what
Richard Damon 在 2022年8月29日 星期一上午10:47:08 [UTC+8] 的信中寫道:
On 8/27/22 7:42 AM, Mark Bourne wrote: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:-)
Jach Feng wrote:Yes, fundamental issue is that the statement
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()
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
you tell it to. :)
ChrisA
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.
--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:-)
Richard Damon
"from x import y" doesn't hide x - it just grabs y. Python does what
you tell it to. :)
ChrisABut 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?
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:
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. :)
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
Jach Feng wrote:When using dot notation to change variable, no matter if 'x.y' is a mutable or immutable object, the change
Chris Angelico 在 2022年8月29日 星期一下午1:58:58 [UTC+8] 的信中寫道:`from x import y` does import the whole module x into memory, and adds
On Mon, 29 Aug 2022 at 15:54, Jach Feng <jf...@ms4.hinet.net> wrote: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" doesn't hide x - it just grabs y. Python does what
Richard Damon 在 2022年8月29日 星期一上午10:47:08 [UTC+8] 的信中寫道:
On 8/27/22 7:42 AM, Mark Bourne wrote: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:-)
Jach Feng wrote:Yes, fundamental issue is that the statement
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()
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
you tell it to. :)
ChrisA
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.
The module is imported but it isn't bound to any name in the current
(global) namespace (obviously there must be some variable bound to it, but that's probably a local variable in the importer and it isn't called
`x`). Then the object bound to the name `y` in the loaed module is bound
to the name `y` in the current namespace.
{'__name__': '__main__', '__doc__': None, '__package__': None,from module import func as f
locals()
<function func at 0x7f6faa8269d0>f
Traceback (most recent call last):f.CONSTANT
Traceback (most recent call last):module.CONSTANT
{'__name__': '__main__', '__doc__': None, '__package__': None,import module as m
locals()
<module 'module' from '/home/dn/Projects/ListQuestions/module.py'>m
<function func at 0x7f6faa8269d0>m.func
1m.CONSTANT
Traceback (most recent call last):module
{'__name__': '__main__', '__doc__': None, '__package__': None,import module
locals()
<function func at 0x7f6faa8269d0>module.func
1module.CONSTANT
<module 'module' from '/home/dn/Projects/ListQuestions/module.py'>module
Build module.py as:
***
CONSTANT = 1
def func():
pass
***
then in the terminal:
***
Python 3.9.13 (main, May 18 2022, 00:00:00)
[GCC 11.3.1 20220421 (Red Hat 11.3.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
from module import func as f
The way we do this, is in main.py, call a "globalizer" function in each other file:
# call globalizers to get shortcuts as global variables
funcs.globalizer(interface, variable_dict)
util.globalizer(interface, variable_dict)
sd.globalizer(interface, variable_dict)
tests.globalizer(interface, variable_dict)
ut.globalizer(interface, variable_dict)
Obviously, you may not need a shared interface in which case you can just pass the variable dictionary.
In each file, you have a function:
def globalizer(interface, variables_dict):
# create global variables for this .py file for shared interface and the variables
....
This works well, making sure separate python files shared exactly the same things we want to be global.
---- Joseph S.
Teledyne Confidential; Commercially Sensitive Business Data
-----Original Message-----
From: Stefan Ram <ram@zedat.fu-berlin.de>
Sent: Tuesday, August 30, 2022 1:09 AM
To: python-list@python.org
Subject: Re: How to make a variable's late binding crosses the module boundary?
dn <PythonList@DancesWithMice.info> writes:
Build module.py as:
***
CONSTANT = 1
def func():
pass
***
then in the terminal:
***
Python 3.9.13 (main, May 18 2022, 00:00:00) [GCC 11.3.1 20220421 (Red
Hat 11.3.1-2)] on linux Type "help", "copyright", "credits" or
"license" for more information.
from module import func as f
In CPython one then can also:
print( f.__globals__[ "CONSTANT" ])
import sys
module = sys.modules[ f.__globals__[ "__name__" ]] print( module.CONSTANT ) CONSTANT = module.CONSTANT print( CONSTANT )
from test import *
On 31/08/2022 05.26, Schachner, Joseph (US) wrote:...
From: Stefan Ram <ram@zedat.fu-berlin.de>
In CPython one then can also:CONSTANT = module.CONSTANT print( CONSTANT )
print( f.__globals__[ "CONSTANT" ])
import sys
module = sys.modules[ f.__globals__[ "__name__" ]]
print( module.CONSTANT )
The conversation seems to be wandering some way from the OP. Whereas
both of these answers are clever (and I assume work), the question
becomes: why would you want to do this? (especially as it looks ugly and >'smells' a bit convoluted). An example use-case from your experience?
NB The OP likely reduced the 'problem' to 'minimum-code' for the benefit
of the list, but what is the motivation behind it? Why would one want to
be able to do this? Rationale? Use-case?
The conversation seems to be wandering some way from the OP. Whereas
both of these answers are clever (and I assume work), the question
becomes: why would you want to do this? (especially as it looks ugly and 'smells' a bit convoluted). An example use-case from your experience?
Delving into the list-archive, to get back to the OP: the first message
in the thread quotes another message that's (apparently) not present.
However, in there somewhere is:
from test import *So, the elephant-in-the-room has always been a very stinky 'code-smell'
- which pretty much every text or web-tutorial will say is a bad idea.
Op 30/08/2022 om 23:52 schreef dn:
The conversation seems to be wandering some way from the OP. Whereas
both of these answers are clever (and I assume work), the question
becomes: why would you want to do this? (especially as it looks ugly and
'smells' a bit convoluted). An example use-case from your experience?
Delving into the list-archive, to get back to the OP: the first message
in the thread quotes another message that's (apparently) not present.
However, in there somewhere is:
from test import *So, the elephant-in-the-room has always been a very stinky 'code-smell'
- which pretty much every text or web-tutorial will say is a bad idea.
No that is a red herring. If for some reason a variable in a module has
to be (re)set after import time, it doesn't matter whether someone uses
from module import *
or
from module import resetable_variable
in both cases the module that did the import will not notice the change
in the original module.
focussing on the code smell, is leading the attention away from the
problem.
On 31/08/2022 19.38, Antoon Pardon wrote:
Are you the OP?
Op 30/08/2022 om 23:52 schreef dn:
The conversation seems to be wandering some way from the OP. WhereasNo that is a red herring. If for some reason a variable in a module has
both of these answers are clever (and I assume work), the question
becomes: why would you want to do this? (especially as it looks ugly and >>> 'smells' a bit convoluted). An example use-case from your experience?
Delving into the list-archive, to get back to the OP: the first message
in the thread quotes another message that's (apparently) not present.
However, in there somewhere is:
from test import *So, the elephant-in-the-room has always been a very stinky 'code-smell'
- which pretty much every text or web-tutorial will say is a bad idea.
to be (re)set after import time, it doesn't matter whether someone uses
from module import *
or
from module import resetable_variable
in both cases the module that did the import will not notice the change
in the original module.
focussing on the code smell, is leading the attention away from the
problem.
The behavior has been shown to be exactly that which is (should be)
expected.
Mark Bourne 在 2022年8月29日 星期一下午6:40:59 [UTC+8] 的信中寫道:
Jach Feng wrote:When using dot notation to change variable, no matter if 'x.y' is a mutable or immutable object, the change
Chris Angelico 在 2022年8月29日 星期一下午1:58:58 [UTC+8] 的信中寫道:`from x import y` does import the whole module x into memory, and adds
On Mon, 29 Aug 2022 at 15:54, Jach Feng <jf...@ms4.hinet.net> wrote: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" doesn't hide x - it just grabs y. Python does what
Richard Damon 在 2022年8月29日 星期一上午10:47:08 [UTC+8] 的信中寫道:
On 8/27/22 7:42 AM, Mark Bourne wrote: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:-)
Jach Feng wrote:Yes, fundamental issue is that the statement
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()
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
you tell it to. :)
ChrisA
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.
will be seen in both modules except those early bindings.
--Jach
Jach Feng wrote:Good Point! I learn from it:-)
Mark Bourne 在 2022年8月29日 星期一下午6:40:59 [UTC+8] 的信中寫道:
Jach Feng wrote:When using dot notation to change variable, no matter if 'x.y' is a mutable or immutable object, the change
Chris Angelico 在 2022年8月29日 星期一下午1:58:58 [UTC+8] 的信中寫道:`from x import y` does import the whole module x into memory, and adds
On Mon, 29 Aug 2022 at 15:54, Jach Feng <jf...@ms4.hinet.net> wrote: >>>>>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?
Richard Damon 在 2022年8月29日 星期一上午10:47:08 [UTC+8] 的信中寫道:"from x import y" doesn't hide x - it just grabs y. Python does what >>>> you tell it to. :)
On 8/27/22 7:42 AM, Mark Bourne wrote: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:-)
Jach Feng wrote:Yes, fundamental issue is that the statement
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()
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
ChrisA
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.
will be seen in both modules except those early bindings.
--JachYes, 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.
I found that using "from test import *" in test2.py makes test2's relation
to "test" almost like the function's relation to the module where it is defined. You can refer to all the variables of the module
On 8/31/22, Jach Feng <jf...@ms4.hinet.net> wrote:Thank you for pointing out these important difference:-)
I found that using "from test import *" in test2.py makes test2's relation to "test" almost like the function's relation to the module where it is defined. You can refer to all the variables of the moduleNote that in general, if __all__ doesn't exist to explicitly define
the contents of a star import, then it imports everything except names
that begin with an underscore.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 300 |
Nodes: | 16 (2 / 14) |
Uptime: | 77:56:23 |
Calls: | 6,716 |
Files: | 12,247 |
Messages: | 5,357,827 |