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