Python——跨文件类中isinstance函数困境


不同文件为入口文件时

  • 文件一(fruit.py):

    1
    2
    3
    4
    5
    6
    7
    # file: fruit.py
    class Apple:
    def __init__(self):
    name = "HongFuShi"

    apple = Apple()
    print apple.__class__
  • 文件二(run.py):

    1
    2
    # file: run.py
    import fruit
  • 考虑一个文件名为 fruit.py 的文件夹中定义了一个类Apple,同时初始化一个对象apple

    • 若执行 python fruit.py
      • 输出 “main.Apple”
    • 若将当前文件导入到另一个文件 run.py 中,然后执行python run.py
      • 输出 “fruit.Apple”
    • 也就是说,执行不同文件,类 Apple 的前缀不同

跨文件类中isinstance函数的困境

  • 困境说明:isinstance的困境:看起来是同一个类,但执行isinstance后返回False

  • 文件一(fruit.py):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # file: fruit.py
    class Apple(object):
    pass

    if __name__ == "__main__":
    from getapple import get_apple # 注意,这里 import 必须放到 "__main__" 中,不能放到外面,否则会发生文件的递归依赖,出现初始化错误
    apple1 = Apple()
    print apple1.__class__ # <class '__main__.Apple'>
    apple2 = get_apple()
    print apple2.__class__ # <class 'fruit.Apple'>
    print isinstance(apple2, Apple) # False
  • 文件二(getapple.py):

    1
    2
    3
    4
    5
    6
    7
    # file: getapple.py
    from fruit import Apple

    def get_apple():
    apple = Apple()
    print apple.__class__ # <class 'fruit.Apple'>
    return apple
  • 此时执行 python getapple.py,无任何输出(符合预期,因为这里 getapple.py 只是用于定义函数)

  • 若执行 python fruit.py,则输出如下:

    1
    2
    3
    4
    <class '__main__.Apple'>
    <class 'fruit.Apple'>
    <class 'fruit.Apple'>
    False
    • 此时 fruit.py 是程序的入口文件
    • 在入口文件中执行 apple1 = Apple() 后得到的类将是 __main__.Apple
    • 在入口文件被导入到 getapple.py 文件中后,执行 apple2 = Apple() 后得到的类将是 fruit.Apple
    • 此时,由于下面的原因造成 isinstance(apple2, Apple) 返回 False
      • apple2 的类别是 fruit.Apple(在 getapple.py 中定义的)
      • Apple__main__.Apple(在 fruit.py 中定义的)
  • isinstance的困境总结:看起来是同一个类,但执行isinstance后返回False