99% right -- but see below.
> Presuming you don't want to use a try statement,
I used to, but that's clumsy and error-prone. E.g., you have to remember
to catch both TypeError (in case the object doesn't have attributes) and
AttributeError (in case it does have attributes but not __class__).
"try" is just the wrong tool for this job.
> how about writing it like this:
>
> ! if hasattr(object, '__class__') and \
> ! object.__class__ is TheSpecificUserDefinedClassOfInterest:
> ! # object is an instance of TheSpecificUserDefinedClassOfInterest
Probably because the last time I thought about it predates hasattr <wink>.
I like it, except that I know Majewski is writing code <grin>:
> I know very few ways to cheat with this (e.g. you can't give a *class*
> object a __class__ attribute -- the only way would be for an extension
> written in C to define an object type with a __class__ attribute that
> might be a class but has a different meaning...)
Two counter-examples, staying entirely within Python:
class dummy: pass
_instance_type = type(dummy())
del dummy
class A: pass
import __main__
__main__.__class__ = A # Steve spoofs a module with ease
A.__dict__['__class__'] = A # spoofing a class is trickier, but doable
a = A()
for obj in a, A, __main__: # new method fooled (prints 'yes' 3 times)
if hasattr(obj,'__class__') and obj.__class__ is A:
print 'yes'
else:
print 'no'
for obj in a, A, __main__: # old method unfooled (prints yes,no,no)
if type(obj) is _instance_type and obj.__class__ is A:
print 'yes'
else:
print 'no'
I'm certainly not asking that you plug these little holes, and I'll use
your suggestion anyway -- just think it's an interesting example!
wiseassedly y'rs - tim
Tim Peters tim@ksr.com
not speaking for Kendall Square Research Corp