On 31Oct2019 20:44, Jach Fong <jf...@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 <c...@cskk.id.au>
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to