略微令人惊讶的行为。不同模块中具有相同名称的两个类共享相同的名称。 (不是相等,这是预期的,但字符串对象标识!)
我不支持它真的很重要,但是有谁知道为什么,以及是否有任何潜在的进一步意外?
演示(在a/a.py
和b/b.py
中有__init__.py
和a/
以及空b/
>>> from a import a
>>> from b import b
>>> ta = a.Test()
>>> tb = b.Test()
>>> ta.__class__.__name__
'Test'
>>> tb.__class__.__name__
'Test'
>>> tb.__class__.__name__ is ta.__class__.__name__ # unexpected
True
>>> ta.__class__
<class 'a.a.Test'>
>>> tb.__class__
<class 'b.b.Test'>
答案 0 :(得分:2)
这是CPython解释器的实现细节。
实习生标识符字符串;只为源代码字符串创建一个副本,并在出现完全相同的字符串值的任何地方重复使用。这使得字典包含测试更快(首先尝试指针比较)。
您可以使用sys.intern()
function为自己的字符串执行此操作,这有助于注意:
通常,Python程序中使用的名称会自动实现,而用于保存模块,类或实例属性的字典具有实习键。
答案 1 :(得分:0)
正如你所指出的那样 - 你不能依赖于刺痛物体是相同的 - 也不是它们是不同的物体。 (当然,除非你明确地引用了相同的字符串)。
如果要比较名称,只需使用==
对象即可。如果你想知道这些类是否相同,那么它们会使用is
运算符和类本身,而不是它们的名称。
答案 2 :(得分:0)
在Python中,一切都是对象/类。无论你写一个类或函数,它的类型都是类型。
问题是你有2个差异类a和b。这两行创建了两个类的2个实例。
>>> ta = a.Test()
>>> tb = b.Test()
每个对象返回类测试上的函数测试。 __ class __ 的类返回对象的对象类型或 __ repr __ 。 名称以字符串的形式返回类的名称。如果您要确认输入此内容并查看类型(tb。类。名称)。所以
>>> tb.__class__.__name__ is ta.__class__.__name__
这是正确的,因为 str 是类型的其他。