InstanceType tests in Python-3.0

R

Robin Becker

I'm in the process of porting some code. I have 2.x code that looks like this

t = type(e)
if t==InstanceType:
return f0(e)
elif t in (float,int):
return f1(e)
else:
return str(e)

In python 3.0 everything has been unified and people say use attributes to tell
what should be done in such a branch. However, this is the real world and this
code is fairly complex. Originally we had a distinction between user defined
class instances and those of the builtins like float, int, str etc etc. Is there
any way for me to tell if an object is an instance of a used defined class which
can then be tested further perhaps?
 
S

Steven D'Aprano

I'm in the process of porting some code. I have 2.x code that looks like
this

t = type(e)
if t==InstanceType:
return f0(e)
elif t in (float,int):
return f1(e)
else:
return str(e)

What happens if e is an instance of a subclass of int, or str?

I'd write the above like this:

if isinstance(e, type.InstanceType):
# old-style classes don't exist in Python 3
return f0(e)
elif isinstance(e, (float, int)):
return f1(e)
else:
return str(e)

Now all you have to do is work out what to do with new-style classes...


In python 3.0 everything has been unified and people say use attributes
to tell what should be done in such a branch.

Well, you know what people say about people who listen to everything
people say.

What do you mean "everything" has been unified?

What do you mean "use attributes to tell what should be done"?

However, this is the real world

No, this is SPARTA!!!

(Sorry, I couldn't resist. And I didn't even like the movie.)

and this code is fairly complex. Originally we had a distinction
between user defined class instances and those of the builtins like
float, int, str etc etc. Is there any way for me to tell if an object is
an instance of a used defined class which can then be tested further
perhaps?

Why do you care if it is a user-defined class or not? What are you
actually trying to accomplish? What's your aim in doing this testing?
 
R

Robin Becker

Steven said:
What happens if e is an instance of a subclass of int, or str?

I'd write the above like this:

if isinstance(e, type.InstanceType):
# old-style classes don't exist in Python 3
return f0(e)
elif isinstance(e, (float, int)):
return f1(e)
else:
return str(e)

Now all you have to do is work out what to do with new-style classes...

except that unfortunately python 3.0 doesn't have type.InstanceType and module
types doesn't have those old style ones any more :(

.........

No, this is SPARTA!!!

(Sorry, I couldn't resist. And I didn't even like the movie.)

nobody expects the Spartacists any more :)
........

Why do you care if it is a user-defined class or not? What are you
actually trying to accomplish? What's your aim in doing this testing?
This is a formatting function it either expects primitives like string/number or
a structured object. Usually an object that has been entered into a lookup table
or one that needs to be rendered using a formatting function defined on the object.

In the old world (with inquisitions)we could tell the difference between user
class instances and other types (effectively primitive types). Since I'm trying
to write out pdf we wanted to treat numerics specially by formatting them with a
predefined number of decimals (anything else is wasted), but essentially the int
branch too could be just str(e).
 
C

Christian Heimes

Robin said:
except that unfortunately python 3.0 doesn't have type.InstanceType and module
types doesn't have those old style ones any more :(

Old style classes and hence InstanceType are gone in py3k.

Christian
 
S

Steven D'Aprano

except that unfortunately python 3.0 doesn't have type.InstanceType and
module types doesn't have those old style ones any more :(

That's because they don't exist in Python 3.0. Classic classes have
passed on, they are no more, they have ceased to be, expired and gone to
meet their maker, bereft of code, resting in peace, shuffled off this
mortal coil and joined the choir invisibile! They are ex-classes!

*wink*

This is a formatting function it either expects primitives like
string/number or a structured object. Usually an object that has been
entered into a lookup table or one that needs to be rendered using a
formatting function defined on the object.

In the old world (with inquisitions)we could tell the difference between
user class instances and other types (effectively primitive types).
Since I'm trying to write out pdf we wanted to treat numerics specially
by formatting them with a predefined number of decimals (anything else
is wasted), but essentially the int branch too could be just str(e).

The way I see it, your code don't really care about the distinction
between "user-generated classes" and "built-in types", it cares about the
distinction between "classes I know about" and "other classes".

In fact, your existing code doesn't even catch all examples of user-
generated classes. It (or at least the snippet you have posted) has no
branch catching new-style classes.
.... pass
........ pass
....False


If I've understand your needs correctly, I'd just write something like
this:


if isinstance(e, (float, int)):
return f1(e)
else:
try:
return f0(e)
except TypeError:
return str(e)


Your f0() function may need to be a little smarter about how it deals
with arbitrary arguments.
 
R

Robin Becker

Steven said:
On Thu, 14 Feb 2008 17:21:20 +0000, Robin Becker wrote:

........

The way I see it, your code don't really care about the distinction
between "user-generated classes" and "built-in types", it cares about the
distinction between "classes I know about" and "other classes".

In fact, your existing code doesn't even catch all examples of user-
generated classes. It (or at least the snippet you have posted) has no
branch catching new-style classes.
.......
in fact there are no old style classes in 3.0 any more. There appears to
be a distinction between types and classes, but I'm not going to rely on
that. Have to recode all of that polymorphic stuff :(
 
C

Carl Banks

I'm in the process of porting some code. I have 2.x code that looks like this

t = type(e)
if t==InstanceType:
return f0(e)
elif t in (float,int):
return f1(e)
else:
return str(e)

In python 3.0 everything has been unified and people say use attributes to tell
what should be done in such a branch. However, this is the real world and this
code is fairly complex. Originally we had a distinction between user defined
class instances and those of the builtins like float, int, str etc etc. Is there
any way for me to tell if an object is an instance of a used defined class which
can then be tested further perhaps?


Here's something that'll work kind of sometimes.


def is_probably_user_defined_class(cls):
try:
modname = cls.__module__
except AttributeError:
return False
try:
mod = sys.modules[modname]
except KeyError:
return False
try:
filename = mod.__file__
except AttributeError:
return False
return filename.endswith('.pyc')


Carl Banks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,196
Latest member
ScottChare

Latest Threads

Top