Re: myfile.py: a Class wrapper for file objects & prompting readlines()

Tim Peters (tim@ksr.com)
Fri, 04 Mar 94 23:35:18 EST

> > [tim]
> > ... when I need to know whether an object belongs to a specific
> > user-defined class ... I don't know a better way to do that than
> >
> > if type(object) is type(_Some_UserDefinedClassInstance) and \
> > object.__class__ is TheSpecificUserDefinedClassOfInterest:
> > # object is an instance of TheSpecificUserDefinedClassOfInterest
> [guido]
> The only reason why you test for type(object) is that you want to be
> sure that object.__class__ doesn't raise an exception.

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