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