nigel222 nigel222 - 7 days ago 5
Python Question

classes with same name in different modules share exact same name string?

Slightly surprising behaviour. Two classes with the same name in different modules share the same name. (Not equality, which is expected, but string object identity! )

I don't support it really matters much, but does anyone know why, and whether there's any potential here for further surprises?

Demo (with

a/a.py
and
b/b.py
and empty
__init__.py
in
a/
and
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'>

Answer

This is an implementation detail of the CPython interpreter.

It interns identifier strings; only one copy is created for source code strings, and re-used everywhere the exact same string value appears. This makes dictionary containment tests faster (by trying pointer comparisons first).

You can do this for your own strings with the sys.intern() function, which helpfully notes:

Normally, the names used in Python programs are automatically interned, and the dictionaries used to hold module, class or instance attributes have interned keys.

Also see About the changing id of a Python immutable string