There is a strange behavior of isinstance if used in __main__
space.
Consider the following code
a.py:
class A(object):
pass
if __name__ == "__main__":
from b import B
b = B()
print(isinstance(b, A))
b.py
from a import A
class B(A):
pass
main.py
from a import A
from b import B
b = B()
print(isinstance(b, A))
When I run main.py
, I get True
, as expected, but when I run a.py
, I am getting False
. It looks like the name of A
is getting the prefix __main__
there.
How can I get a consistent behavior? I need this trick with import of B
in a.py
to run doctest
on file a.py
.
WSo what happens when you run a.py
is that Python reads a.py
and executes it. While doing so, it imports module b
, which imports module a
, but it does not reuse the definitions from parsing it earlier. So now you have two copies of the definitions inside a.py
, known as modules __main__
and a
and thus different __main__.A
and aA
.
In general you should avoid importing modules that you are executing as well. Rather you can create a new file for running doctests and use something like
import a
import doctest
doctest.testmod(a)
and remove the __main__
part from module a
.
Chain of events:
class A
statement is executed, creating A
in the __main__
namespace. b
is imported. a
is imported. class A
statement is executed, creating A
in the a
namespace. This A
in the a
namespace has no relation to the A
in the __main__
namespace other than having been generated by the same code. They are different objects. I agree with Helmut that it is best to avoid such circular imports. However, if you wish to fix your code with minimal changes, you could do the following:
Let's rename b.py
--> bmodule.py
so we can distinguish b
the module from b
the variable (hopefully in your real code these names are already distinct):
class A(object):
pass
if __name__ == "__main__":
import bmodule
b = bmodule.B()
print(isinstance(b, bmodule.A))
prints
True
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.