不同模块中具有相同名称的类共享完全相同的名称字符串?

时间:2016-11-30 12:07:57

标签: python

略微令人惊讶的行为。不同模块中具有相同名称的两个类共享相同的名称。 (不是相等,这是预期的,但字符串对象标识!)

我不支持它真的很重要,但是有谁知道为什么,以及是否有任何潜在的进一步意外?

演示(在a/a.pyb/b.py中有__init__.pya/以及空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'>

3 个答案:

答案 0 :(得分:2)

这是CPython解释器的实现细节。

实习生标识符字符串;只为源代码字符串创建一个副本,并在出现完全相同的字符串值的任何地方重复使用。这使得字典包含测试更快(首先尝试指针比较)。

您可以使用sys.intern() function为自己的字符串执行此操作,这有助于注意:

  

通常,Python程序中使用的名称会自动实现,而用于保存模块,类或实例属性的字典具有实习键。

另见About the changing id of a Python immutable string

答案 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 类型的其他。