Type of an object:
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Tue Dec 17 10:08:51 EST 2013
On Tue, 17 Dec 2013 23:35:10 +1300, Gregory Ewing wrote:
> Steven D'Aprano wrote:
>> I think I need to see an actual working demonstration, because as far
>> as I can see, type(obj) returns obj.__class__.
>
> Nope:
>
> >>> class C(object):
> ... def f(self):
> ... return "Surprise!"
> ... __class__ = property(f)
> ...
> >>> c = C()
> >>> type(c)
> <class '__main__.C'>
> >>> c.__class__
> 'Surprise!'
Well, that is a surprise, but I don't think that is intended behaviour. I
think that's something which only works by accident. The intention is
that __class__ returns the instance's type, not arbitrary values. If you
try to set it to a non-class on the instance, it fails:
py> class D(object):
... pass
...
py> d = D()
py> d.__class__ = property(lambda self: 'Surprise!')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __class__ must be set to a class, not 'property' object
Same when you try to set it on the class object itself:
py> D.__class__ = property(lambda self: 'Surprise!')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __class__ must be set to a class, not 'property' object
So my guess is that the fact that your code works at all is an accident.
I can demonstrate that changing the __class__ of an instance causes
type(obj) to return a different value, and also to dynamically change the
behaviour of the object:
py> class Spam(object):
... def method(self):
... return "spam"
...
py> class Ham(object):
... def method(self):
... return "ham"
...
py> ham = Ham()
py> ham.method()
'ham'
py> ham.__class__ = Spam
py> ham.method()
'spam'
py> type(ham)
<class '__main__.Spam'>
So this is a case where type(obj) returns obj.__class__ rather than it's
internal type field. That's the point I was trying to make: type(obj) may
return obj's internal type field, but if you set obj.__class__, type(obj)
will then return the new class, not the internal one.
--
Steven
More information about the Python-list
mailing list