Class 从两个不同的路径导入不相等?

Class imported from two different paths is not equal?

使用两个不同的PYTHONPATH导入的实体似乎不是相同的对象。

我在我的代码中遇到了一个小问题,我想用一个小测试用例来解释它。

我创建了源代码树:

a/
  __init__.py
  b/
    __init__.py
    example.py

在example.py中:

class Example:
  pass

从文件夹 a 的父文件夹,我 运行 python 和这个测试:

>>> import sys
>>> sys.path.append("/home/marco/temp/a")
>>> 
>>> import a.b.example as example1
>>> import b.example as example2
>>> 
>>> example1.Example is example2.Example
False

那么问题来了:为什么结果是False?即使通过两个不同的路径导入,class 也是相同的。如果 class 是自定义异常并且您尝试使用 except.

捕获它,这将是一团糟

使用 python 3.4.3

测试

is运算符用于检查两个名称是否指向同一个对象(内存位置)。

example1.Example is example2.Example

显然没有指向相同的位置,因为您两次导入相同的对象。

但是,如果你做了类似的事情:

a, b = example1.Example, example1.Example

a is b # True

相反,您应该使用 == 运算符:

example1.Example == example2.Example
True

请注意,如果您不实施 __eq____hash__,默认行为与 is

相同

在Python中,class语句是一个可执行语句,所以每次执行它都会创建一个新的class。

导入模块时 Python 将检查 sys.modules 以查看指定路径中的模块是否已存在。如果是,那么您将只返回相同的模块,否则它将尝试加载该模块并执行它包含的代码。

因此同一模块的两个不同路径将加载代码两次,这将执行 class 语句两次,并且您定义了两个独立的 classes。

当人们有一个文件 a.py,他们 运行 作为脚本,然后在另一个模块中尝试导入 a 时,这通常会影响到人们。该脚本作为 __main__ 加载,因此具有与导入模块不同的 classes 和不同的全局变量。

道德是,在引用模块的方式上始终保持一致。