python circular import and definition of exception classes -
i know way python acts circular imports through creating references in sys.modules. please see these 2 modules , problem defining exception class:
a.py
import b class err(exception): pass if __name__ == '__main__': try: b.f() except err: pass b.py
from import err def f(): raise err() seems should catch err it's not correct. output of running a.py is:
$ python a.py traceback (most recent call last): file "a.py", line 8, in <module> b.f() file "b.py", line 4, in f raise err() a.err ok, let add logs code make more clear:
a.py:
print 'a1' import b print 'a2' class err(exception): pass print 'a3', 'id(err)=%x' % id(err) if __name__ == '__main__': try: b.f() except err: pass b.py
print 'b1' import err print 'b2', 'id(err)=%x' % id(err) def f(): raise err() the output is:
$ py a.py a1 b1 a1 a2 a3 id(err)=23fa750 b2 id(err)=23fa750 a2 a3 id(err)=23f9740 traceback (most recent call last): file "a.py", line 12, in <module> b.f() file "b.py", line 7, in f raise err() a.err as can see python defines err 2 times , there 2 different class object err @ 0x23fa750 , 0x23f9740. if test instance of b.err isinstance function , a.err class false. way catch exception use b.err instead of err. it's not expect @ first sight , it's not want.
the solution know create new module c.py , define err class in it. both a.py , b.py should import err c.py. solves problem.
but there solution allow define err in a.py? note problem not exception classes, python class may fall pit based on how use objects in our code.
when add if __name__ == '__main__': @ end of module reference things defined in preceding code, it's not same importing , using module (the __main__ module not cached in sys.modules, 1 thing). can first example work correctly following modification:
a.py
import b class err(exception): pass if __name__ == '__main__': import err # add try: b.f() except err: pass output:
... nothing, correct
Comments
Post a Comment