InstanceType tests in Python-3.0

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Thu Feb 14 23:20:13 CET 2008


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

> Steven D'Aprano wrote:
>> On Thu, 14 Feb 2008 15:26:08 +0000, Robin Becker wrote:
>> 
>>> 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...
>> 
>> 
> 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*


>> 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).

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.

>>> from types import InstanceType
>>> class Parrot:  # classic class
...     pass
...
>>> type(Parrot()) == InstanceType
True
>>> class NewParrot(object):  # new-style class
...     pass
...
>>> type(NewParrot()) == InstanceType
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.


-- 
Steven



More information about the Python-list mailing list