[Python-Dev] type(obj) vs. obj.__class__

Martin Panter vadmium+py at gmail.com
Sun Oct 18 04:07:07 EDT 2015


On 18 October 2015 at 05:55, Steven D'Aprano <steve at pearwood.info> wrote:
> On Sat, Oct 17, 2015 at 03:45:19PM -0600, Eric Snow wrote:
>> So, would it make sense to establish some concrete guidelines about
>> when to use type(obj) vs. obj.__class__?  If so, what would those be?
>> It may also be helpful to enumerate use cases for "type(obj) is not
>> obj.__class__".
>
> I for one would like to see a definitive explanation for when they are
> different, and when you should use one or the other. The only
> obvious example I've seen is the RingBuffer from the Python Cookbook:
>
> http://code.activestate.com/recipes/68429-ring-buffer/

It looks like this example just assigns to the existing __class__
attribute, to switch to a different class. I haven’t seen this ability
mentioned in the documentation, but I suspect it is meant to be
supported. However assigning to __class__ like that should
automatically update the type() return value, so type(ring_buffer) ==
ring_buffer.__class__ is still maintained.

Perhaps some of this confusion comes from Python 2. I don’t know the
details, but I know in Python 2, type() can do something different, so
you have to use __class__ directly if you want to be compatible with
Python 2 classes. But in Python 3 code I prefer using direct function
calls like type() to “special attributes” like __class__ where
practical.

The documentation says that __*__ names are reserved for Python and
its built-in library, rather than user code. So user code that creates
a class attribute or property called __class__ is asking for trouble
IMO, and we shouldn’t spend much effort accommodating such cases.

For __repr__() I would use type(), which seems to agree with what
object.__repr__() uses.


More information about the Python-Dev mailing list