对于通过包导入的类型和直接从同一模块导入的类型

对于通过包导入的类型和直接从同一模块导入的类型

本文介绍了对于通过包导入的类型和直接从同一模块导入的类型,isinstance 失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

/Project
|-- main.py
|--/lib
|  |--__init__.py
|  |--foo.py
|  |--Types.py

/Project/lib 已添加到 PYTHONPATH 变量中.

/Project/lib has been added to the PYTHONPATH variables.

Types.py:

class Custom(object):
    def __init__(self):
        a = 1
        b = 2

foo.py:

from Types import Custom
def foo(o):
    assert isinstance(o, Custom)

最后,来自 ma​​in.py:

from lib.Types import Custom
from lib.foo import foo
a = Custom()
foo(a)

现在的问题是,alib.foo.Custom 类型,而 isinstance 调用将检查它是否等于 foo.Custom,显然返回false.

The problem now is, that a is of type lib.foo.Custom, while the isinstance call will check if it equals foo.Custom, which obviously returns false.

如何避免这个问题,而不必更改库 (lib) 中的任何内容?

How can I avoid this problem, without having to change anything in the library (lib)?

推荐答案

你不应该把 lib 做成一个包,然后把它添加到 PYTHONPATH.这使得可以将其模块作为 lib. 和直接导入,从而为失败做好准备.

You should not both make lib a package and add it to PYTHONPATH. This makes it possible to import its modules both as lib. and directly, setting yourself up for failure.

如你所见,

lib.Types.Custom != Types.Custom

因为Python 导入的工作方式.

Python 搜索导入路径并解析它找到的适当条目.

Python searches the import path and parses an appropriate entry that it finds.

  • 当你导入lib.Types时,它会导入lib目录作为一个包,然后lib/Types.py作为一个子模块在里面它,在 sys.modules 中创建模块对象 liblib.Types.
  • 当您导入 Types 时,它会将 Types.py 作为独立模块导入,从而在 sys.xml 中创建模块对象 Types.模块.
  • When you import lib.Types, it imports the lib directory as a package, then lib/Types.py as a submodule inside it, creating module objects lib and lib.Types in sys.modules.
  • When you import Types, it imports Types.py as a standalone module, creating a module object Types in sys.modules.

因此,Typeslib.Types 最终成为两个不同的模块对象.Python 不会检查它们是否是同一个文件,以保持简单并避免猜测你.

So, Types and lib.Types end up as two different module objects. Python doesn't check if they are the same file to keep things simple and to avoid second-guessing you.

(这实际上列在 Python 导入系统中的陷阱 文章称为双重导入陷阱".)

(This is actually listed in the Traps for the Unwary in Python’s Import System article as the "double import trap".)

如果您从 PYTHONPATH 中删除 liblib/foo.py 中的导入将需要成为相对导入:

If you remove lib from PYTHONPATH, the import in lib/foo.py would need to become a relative import:

from .Types import Custom

或绝对导入:

from lib.Types import Custom

这篇关于对于通过包导入的类型和直接从同一模块导入的类型,isinstance 失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-26 15:21