isinstance behavior with module reload

2019-07-14 17:44发布

Given the following two .py files:

aclass.py

class A(object):
    pass

main.py

def importer(klass):
    """
    Used to import classes from there python qalname
    """
    import_ = lambda m, k: getattr(__import__(m, fromlist=k), k)
    klass = klass.split('.')
    module = '.'.join(klass[:-1])
    klass = klass[-1]
    return import_(module, klass)

from aclass import A

import_A = importer('aclass.A')
print isinstance(A(), import_A)  # Expected to be true 
print isinstance(import_A(), A)  # Expected to be true 

At this stage, everything works fine (my program prints True\nTrue) But if I modify the importer method to enforce a reload, ie:

this line:

    import_ = lambda m, k: getattr(__import__(m, fromlist=k), k)

is replaced by:

    import_ = lambda m, k: getattr(reload(__import__(m, fromlist=k)), k)

my programs returns

False
False

And I do not understand this behavior.

1条回答
别忘想泡老子
2楼-- · 2019-07-14 17:56

Reloading a module means re-executing its content, in this case class A(object): pass. So it creates another different class. It's the same behavior as:

class A(object):
    pass
a = A()
class A(object):          # a different class
    pass
print isinstance(a, A)    # False

This should be enough to explain why a bare reload() is usually a bad idea. I'm sure others could point to frameworks that implement more sophisticated reloading procedures, e.g. patching the old class to be considered equal to the new one.

查看更多
登录 后发表回答