What's the difference between running a script under command box and interpreter?
jfong at ms4.hinet.net
jfong at ms4.hinet.net
Fri Nov 1 01:03:28 EDT 2019
Cameron Simpson於 2019年11月1日星期五 UTC+8下午12時13分45秒寫道:
> On 31Oct2019 20:44, Jach Fong <jfong at ms4.hinet.net> wrote:
> >The script test.py is something like this:
> >-------test.py
> >from pyeds import fsm
> >...
> >...
> >class Rule_Parse:
> > def __init__(self):
> > ...
> > self.current_char = ''
> >...
> >...
> >def main(input_str):
> > for c in input_str:
> > ...
> > rule.current_char = c
> > ...
> >
> >if __name__ == '__main__':
> > input_str = '(NNS(acoustics) & RB(not)) | JJ(muted)'
> > rule = Rule_Parse()
> > main(input_str)
> > ...
> >
> >-----------
> >The test.py can run correctly under command box:
> >D:\Works\Python\pyeds-master\src>py test.py
> >
> >but fails when running under interpreter:
> >D:\Works\Python\pyeds-master\src>py
> >Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 32 bit (Intel)] on win32
> >Type "help", "copyright", "credits" or "license" for more information.
> >>>> from test import *
> >>>> input_str = "(NNS(acoustics) & RB(not)) | JJ(muted)"
> >>>> rule = Rule_Parse()
> >>>> main(input_str)
> >Traceback (most recent call last):
> > File "<stdin>", line 1, in <module>
> > File "D:\Works\Python\pyeds-master\src\test.py", line 229, in main
> > rule.current_char = c
> >NameError: name 'rule' is not defined
> >>>>
> >
> >I did check the globals using dir() and the 'rule' is there, no doubt.
>
> It matters how you checked this. This isn't apparent.
>
> >I also tried "py -m pdb test.py" and step through it, no problem too.
>
> This:
> py test.py
> and this:
> py -m pdb test
>
> both run test.py with __name__ set to "__main__" to indicate that
> test.py is the main programme.
>
> When you "import test", the module's __name__ is from the import
> ("test") i.e. not the main programme.
>
> The bottom of your module has an if statement whose body only runs when
> this is the main programme.
>
> The core issue is that the global "rule" is _only_ defined inside that
> if statement.
>
> You might set it unconditionally to None at the start of the file, but
> that would only change the failure mode.
>
> You might set it unconditionally to Rule_Parse() at the top of the file
> but that pointlessly instantiates an instance of Rule_Parse which might
> never be needed (maybe that is cheap, but many other classes are not).
> The basic intent of an import is to define various classes and other
> names, but _not_, generally, to create class instances and do
> significant work.
>
> This is really an example illustrating one reason why global variables
> are considered things to avoid almost all of the time. Had main()
> required "rule" as a parameter then it would not have been possible to
> call it without at least providing a rule. The same applies with most
> other functions: if they all require their external state via parameters
> then you can't miss things out. (You can, of course, always pass
> incorrect values, but that is usually easier to debug.)
>
> Avoid globals; they are usually a source of bugs.
>
> Cheers,
> Cameron Simpson <cs at cskk.id.au>
Yes, the 'if' body is not executed when I import test.py under interpreter, that's why I manually execute them there.
What puzzles me is that the globals() has a 'rule' object in both cases. Why this one doesn't work?
--Jach
More information about the Python-list
mailing list