Pilot cyclic import and definition of exception classes

I know how python works with circular import by creating links in sys.modules. But please review these two modules and the problem of defining an exception class:

a.py

import b
class Err(Exception):
    pass
if __name__ == '__main__':
    try:
        b.f()
    except Err:
        pass

b.py

from a import Err
def f():
    raise Err()

It seems that we should catch Err, but it is not. Conclusion of the work of a.py:

$ 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, now add some codes to the code to make it 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'
from a import Err

print 'B2', 'id(Err)=%x' % id(Err)

def f():
    raise Err()

Conclusion:

$ 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

, python Err Err 0x23fa750 0x23f9740. b.Err isinstance a.Err, False. , - b.Err Err. , , , .

, , c.py Err. a.py b.py Err c.py. .

, Err a.py? , , python , , .

+4
1

if __name__ == '__main__': , , , , ( __main__ sys.modules, ). :

a.py

import b
class Err(Exception):
    pass
if __name__ == '__main__':
    from a import Err  # add this
    try:
        b.f()
    except Err:
        pass

:

... nothing, which is correct
+1

Source: https://habr.com/ru/post/1584706/


All Articles