[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

InstanceType tests in Python-3.0

Robin Becker

2/14/2008 3:26:00 PM

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?
--
Robin Becker

6 Answers

Steven D'Aprano

2/14/2008 3:47:00 PM

0

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



> 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?


--
Steven

Robin Becker

2/14/2008 5:21:00 PM

0

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 :(


>
>> In python 3.0 everything has been unified and people say use attributes
.........
>
> No, this is SPARTA!!!
>
> (Sorry, I couldn't resist. And I didn't even like the movie.)
>
>

nobody expects the Spartacists any more :)

>> and this code is fairly complex. Originally we had a distinction
........
>
> 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).
--
Robin Becker

Christian Heimes

2/14/2008 5:41:00 PM

0

Robin Becker wrote:
> 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

Steven D'Aprano

2/14/2008 10:20:00 PM

0

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

Robin Becker

2/14/2008 10:39:00 PM

0

Steven D'Aprano wrote:
> 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 :(
--
Robin Becker

Carl Banks

2/14/2008 10:58:00 PM

0

On Feb 14, 10:26 am, Robin Becker <ro...@reportlab.com> 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)
>
> 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