1

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'>
nigel222
  • 7,582
  • 1
  • 14
  • 22
  • *"the names used in Python programs are automatically interned"* https://docs.python.org/3/library/sys.html#sys.intern – vaultah Nov 30 '16 at 12:09
  • All Python strings are immutable, so any interning of strings is totally safe. – PM 2Ring Nov 30 '16 at 12:17

3 Answers3

2

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

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Thanks. Google found this, which seems informative: https://books.google.co.uk/books?id=mh0bU6NXrBgC&pg=PA505&lpg=PA505&dq=python+interns+identifiers&source=bl&ots=XznyDpc1hd&sig=fsNqflJ_l0N_UhlALvrPh3S7ETQ&hl=en&sa=X&ved=0ahUKEwj6kYP4udDQAhWlCcAKHTvgD_UQ6AEIKjAC#v=onepage&q=python%20interns%20identifiers&f=false – nigel222 Nov 30 '16 at 12:14
  • @nigel222: that information is rather out of date; see the `sys.intern()` documentation I linked to: *Interned strings are not immortal*; the text you have there states they are. They *used* to be, but only until Python 2.3. – Martijn Pieters Nov 30 '16 at 12:15
  • Yes, out of date, but it had a gentler explanation of what the term "interned" meant! Certainly not to be trusted for Python3 internals hacking! – nigel222 Nov 30 '16 at 12:27
  • @nigel222: sorry, my comment does indeed read harsher than I meant it. :-) – Martijn Pieters Nov 30 '16 at 12:29
0

As youve noted - you can't rely in sting objects being the same - nor in they being different objects. (Unless you explicitly makes references to the same strings, of course).

If you want to compare for the name, just use the == object. If yu want to know if the classes are the same, them use the is operator with the classes themselves, not with their names.

jsbueno
  • 99,910
  • 10
  • 151
  • 209
0

In Python everything is object/class. Whatever you write either a class or function, it's type is type.

In question you have 2 diff classes a and b. Here these 2 lines create 2 instances of both classes.

>>> ta = a.Test()
>>> tb = b.Test()

Function Test on each object return class Test. A class to __class__ returns object type or __repr__ of object. And name returns name of class in form of string. If you want to confirm type this and see type(tb.class.name). So

>>> tb.__class__.__name__ is ta.__class__.__name__

this is returning true as one str is type of other.

Rakesh Kumar
  • 4,319
  • 2
  • 17
  • 30