What's the difference between running a script under command box and interpreter?
Cameron Simpson
cs at cskk.id.au
Sun Nov 3 20:17:26 EST 2019
On 03Nov2019 16:34, Jach Fong <jfong at ms4.hinet.net> wrote:
>Peter J. Holzer於 2019年11月4日星期一 UTC+8上午3時59分36秒寫道:
>> It's not really "the interpreter" (I think you mean the REPL) which
>> has
>> it's own globals. Every module/file has its own globals.
>>
>> The same thing happens non-interactively:
>>
>> % cat test.py
>> def main():
>> print(rule)
>>
>> % cat foo.py
>> #!/usr/bin/python3
>>
>> from test import *
>>
>> rule = 42
>> main()
>>
>> % ./foo.py
>> Traceback (most recent call last):
>> File "./foo.py", line 6, in <module>
>> main()
>> File "/home/hjp/tmp/test.py", line 2, in main
>> print(rule)
>> NameError: name 'rule' is not defined
>>
>> The "rule" identifier in main() refers to a "rule" variable in the
>> module test. If you set a variable "rule" somewhere else (in foo.py or
>> the REPL, ...), that has no effect. How should python know that you want
>> to set the rule variable in the test module? [...]
>
>I innocently thought that when import module through "from test import *", I am working on test's globals under REPL. I didn't noticed the REPL has its own globals.
Aye. An import statement is essentially a funny shaped assignment
statement (aside from the side effect of loading the required module).
When you go:
from blah import foo
You're getting a _local_ variable "foo" which references the same
_value_ that "blah.foo" also references. But it is independent of
"blah.foo"; assigning to it (changing what it references) does not
change what "blah.foo" references.
To take a concrete example, I've a tiny module "cs.x" which essentially
supplies just a single function X() whose purpose it to write a debug
message (no logging modules or other complications). So lots of my dev
code has (while debugging):
from cs.x import X
and then:
X("some message about %s", variable_name)
X() normally just writes to sys.stderr, but it has some module level
mode switches such X_via_tty which literally opens "/dev/tty" and writes
to that, invented for situations where sys.stderr has been intercepted.
Occasionally I need to set that mode (usually in a unit test I'm
debugging). So I go:
from cs.x import X # as normal
import cs.x; cs.x.X_via_tty = True
If I went:
from cs.x import X, X_via_tty
X_via_tty = True
it wouldn't work.
>>>> How should python know that you want to set the rule variable in the test module?
>
>My 'wrong' answer will be, at the time I raised my question, that when
>import two different modules either has 'rule' variable, REPL will see
>the second imported one. No kidding:-)
Well:
from mod1 import rule
from mod2 import rule
is like:
import mod1
import mod2
rule = mod1.rule # copy reference
rule = mod2.rule # copy the other reference
Cheers,
Cameron Simpson <cs at cskk.id.au>
More information about the Python-list
mailing list