似乎使用两个不同的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
?即使通过两个不同的路径导入,该类也是相同的。如果类是自定义异常并且您尝试使用except
来捕获它,那么这是完全混乱。
使用python 3.4.3进行测试
答案 0 :(得分:3)
在Python中,class
语句是一个可执行语句,因此每次执行它时都会创建一个新类。
导入模块时,Python将检查sys.modules
以查看指定路径上的模块是否已存在。如果确实如此,那么你将只返回相同的模块,否则它将尝试加载模块并执行它包含的代码。
因此,同一模块的两个不同路径将加载代码两次,它会执行两次class
语句,并且您将定义两个独立的类。
这通常会在人们拥有文件a.py
时对其进行攻击,这些文件作为脚本运行,然后在另一个模块中尝试导入a
。该脚本作为__main__
加载,因此具有与导入的模块不同的类和不同的全局变量。
道德是,在你引用模块的方式上始终保持一致。
答案 1 :(得分:0)
is
运算符用于检查两个名称是否指向同一对象(内存位置)。
example1.Example is example2.Example
显然没有指向相同的位置,因为您要导入相同的对象两次。
但是,如果你做了类似的事情:
a, b = example1.Example, example1.Example
a is b # True
相反,您应该使用==
运算符:
example1.Example == example2.Example
True
请注意,如果您未实施__eq__
或__hash__
,则默认行为与is
相同