3

Structure:

package/
    m1.py
    m2.py

m1.py:

class A:
    pass


if __name__ == '__main__':
    from m2 import B

    print(issubclass(B, A))

m2.py:

from m1 import A


class B(A):
    pass

I don't now why I get false while I think it's obviously true when I run m1.py. My python version is python3.5.2.

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
Jeffery
  • 307
  • 1
  • 10

4 Answers4

3

Wellcome to the world of modules and namespaces!

Here is what happens:

In module m2, you import A from module m1. So you create a class m2.A as a reference to class m1.A. It happens to have the same definition as __main__.A, but they are different objects, because the main module is named __main__ and not m1. Then in module __main__ you create a class __main__.B as a reference to class m2.B

To better understand what happens here, I have added some code to m1:

...
print(issubclass(B, A))

import m1
import m2
print(A == m1.A, m1.A == m2.A)
print(B == m2.B)
print(issubclass(B, m2.A), issubclass(B, m1.A))

The output is:

False
False True
True
True True

Proving that B is indeed a subclass of m1.A but not of __main__.A.

bryant1410
  • 5,540
  • 4
  • 39
  • 40
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
2

You have to derive class A from object to get issubclass do its job:

isinstance() and issubclass() behavior differently

class A(object): ...

Here an example of python cli:

>>> class A(object): pass
>>> class B(A): pass
>>> issubclass(B,A)
True
Community
  • 1
  • 1
Nicolas Heimann
  • 2,561
  • 16
  • 27
1

You create 2 class objects, derived from the same class. That is: the class code is executed twice and thus results in 2 objects. And those are not the same. Example: see the output of the print statements below

# m2.py
from m1 import A

class B(A):
    pass

print(A)

# m1.py
class A:
    pass

if __name__ == '__main__':
    from m2 import B
    print(A)
    print(issubclass(B, A))

# Output
#<class 'm1.A'>
#<class '__main__.A'>
#False

Also: see this answer for more information.

Community
  • 1
  • 1
Nander Speerstra
  • 1,496
  • 6
  • 24
  • 29
0

IN m1.py you are providing class A and in m2.py you are importing class of A. Even though it is imported from m1.py it is not the same object. You never actually import the exact object you just import the code and a sperate object is created. So instead of importing class A you just had two separate class A() code blocks would you expect them to be a subclass of each other just because they have the same name. You are not checking if the class has the same name you are checking if the class is an subclass of an actual class object (not just the text of the name).

It would be no different than importing class A from a 3rd completely different module because you are just importing code not objects.

bauderr
  • 47
  • 10