By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
444,100 Members | 2,979 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 444,100 IT Pros & Developers. It's quick & easy.

Why is there no instancemethod builtin?

P: n/a
Why hello there ha ha.

I have got in the habit of testing the types of variables with
isinstance and the builtin type names instead of using the types
module, as was the style back around Python 2.1. That is, rather than

if type(x) == types.ListType:

I now do:

if isinstance(x, list):

It is my understanding that this is what people do nowadays. One
problem I have, though, is that not all type names are available as
builtins. Just looking through the types declared in types, the
following are builtins:

bool, buffer, complex, dict, file, float, list, long,
object, slice, str, tuple, type, unicode, xrange, NoneType,
NotImplementedType

And the following are not:

dictproxy, ellipsis, frame, function, instancemethod, module,
traceback, instancemethod, NoneType, NotImplementedType

So for any in the latter batch, I have to import types after all. I
assume the dividing line is whether the name is useful as a
constructor. Still, I feel there's some inconsistencies in the
usefulness of the new type system. Why do str and unicode derive from
basestring, while list and tuple are independent types? list and
tuple support most of the same operations... it seems like either they
should also have an abstract base class or str and unicode shouldn't,
because duck typing doesn't really require that.

It also seems like types may be on the way out, because I don't see
constants for set or frozenset.

I'm not sure I have a question here, just pointing out what I see as
some flaws in the new type system.
Jul 19 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
John Reese wrote:
Why hello there ha ha. [snip]
Just looking through the types declared in types, the following are builtins:
[snip]
... NoneType,
NotImplementedType

And the following are not:
[snip]
... NoneType, NotImplementedType

So for any in the latter batch, I have to import types after all.


Plonk.
Jul 19 '05 #2

P: n/a
John Reese wrote:
I now do:

if isinstance(x, list):

It is my understanding that this is what people do nowadays.


I wouldn't go that far. I don't have an isinstance check for lists
anywhere in my entire codebase. Why do you think you need to check to
see if something is of type list? Why don't you just use it as needed,
and find out, e.g.:

try:
itr = iter(x)
except TypeError:
# do whatever you need to do if it's not iterable
else:
# do whatever you need to do if it *is* iterable

STeVe
Jul 19 '05 #3

P: n/a
On Fri, 17 Jun 2005 16:40:56 -0600, <st************@gmail.com> wrote:
John Reese wrote:
I now do:

if isinstance(x, list):

It is my understanding that this is what people do nowadays.


I wouldn't go that far. I don't have an isinstance check for lists
anywhere in my entire codebase. Why do you think you need to check to
see if something is of type list? Why don't you just use it as needed,
and find out, e.g.:

try:
itr = iter(x)
except TypeError:
# do whatever you need to do if it's not iterable
else:
# do whatever you need to do if it *is* iterable

STeVe


I'm not saying I do it a lot, but sometimes it's useful to write
methods with interfaces like, well, isinstance's, whose second argument
can be a single type object or a sequence of class objects. The
standard conditional vs. exception tradeoffs exist here... if it's
likely that x isn't iterable, I shouldn't have to incur the time and
heap churn penalty of filling in sys.exc_info and its obsolete
cousins, potentially rolling back the stack, etc.
Jul 19 '05 #4

P: n/a
John Reese wrote:
I now do:
if isinstance(x, list): [snip]
I'm not saying I do it a lot, but sometimes it's useful to write
methods with interfaces like, well, isinstance's, whose second argument
can be a single type object or a sequence of class objects.


Personally, I'd just write these functions with a *args instead, e.g.:

def my_isinstance(obj, *types):
return isinstance(obj, types)

Sure, it's not an option if you need multiple type lists, but how often
does that happen?

STeVe
Jul 19 '05 #5

P: n/a
"John Reese" <jt*@ofb.net> wrote in message
news:slrndb6ct5.pho.jt*@ofb.net...
Why hello there ha ha.

I have got in the habit of testing the types of variables with
isinstance and the builtin type names instead of using the types
module, as was the style back around Python 2.1. That is, rather than

if type(x) == types.ListType:

I now do:

if isinstance(x, list):
you need _both_ isinstance and the types module to do a correct
check for any string type: isinstance(fubar, types.StringTypes).
That's because both string and unicode are subtypes of one base.
It is my understanding that this is what people do nowadays. One
problem I have, though, is that not all type names are available as
builtins. Just looking through the types declared in types, the
following are builtins:

bool, buffer, complex, dict, file, float, list, long,
object, slice, str, tuple, type, unicode, xrange, NoneType,
NotImplementedType

And the following are not:

dictproxy, ellipsis, frame, function, instancemethod, module,
traceback, instancemethod, NoneType, NotImplementedType


You need to do your homework better. You have, for example
NoneType and NotImplementedType in both lists.

The basic answer to your question is that the types in builtins
are there because they have uses other than type checks.
Being useful for type checks is not the criterion for being in
builtins. That's the function of the types module.

The other point to be made here is that, in most cases,
type checks are a design smell. That's not always true, but
it's the first thing to check when you see one.

John Roth

Jul 19 '05 #6

P: n/a
"Steven Bethard" wrote:
John Reese wrote:
I now do:

if isinstance(x, list):

It is my understanding that this is what people do nowadays.


I wouldn't go that far. I don't have an isinstance check for lists
anywhere in my entire codebase. Why do you think you need to check to
see if something is of type list? Why don't you just use it as needed,
and find out, e.g.:

try:
itr = iter(x)
except TypeError:
# do whatever you need to do if it's not iterable
else:
# do whatever you need to do if it *is* iterable


A class of cases I've found necessary to do explicit type checking is
when a different action is taken for different types, but where duck
typing can't distinguish between them. For example, a function that
returns a string representation of an S-expression, represented as a
list of nested lists:

def s_expr(obj):
if isinstance(obj, list):
return "(%s)" % ' '.join(map(s_expr,obj))
else:
return str(obj)
s_expr([1, [2,3], [4,5], "foo"])
'(1 (2 3) (4 5) foo)'


Here duck typing doesn't help because the function should take the if
branch only for lists and not other iterables (e.g. strings).

George

Jul 19 '05 #7

P: n/a
[George Sakkis]
The fact that strings don't have __iter__ is an implementation
detail. I can't think of any reason other than historic and perhaps
backwards compatibility for this;
iterables should IMHO by definition be exactly
the objects with __iter__).
There would be no benefit other than satisfying that particular world
view. It is a feature that all sequences are automatically iterable
without having to write a custom __iter__ method. That makes life a
bit easier for writers of sequence-like classes.

[Michele Simionato] I think strings do not have __iter__ on purpose, exactly to
distinguish them from other iterables, since sometimes it is nice
to consider them atomic, but I am not sure of this. You should
ask the developers.
That is not correct. Since any sequence is automatically iterable
(because of the presence of __getitem__), the inclusion of a separate
__iter__ method is purely optional. The option to include a custom
__iter__ method has been exercised only when it has offered some
performance benefit. IOW, the inclusion of __iter__ for a sequence is
an arbitrary implementation detail -- there is no other significance.

Anyway, the right definition of iterable is
(as I was told) "an object X such that iter(X) does not throw an
exception". Objects following the __getitem__ protocol
- such as strings -are iterables even if they do not have
an __iter__ method.


An object is iterable if and only if it provides either __iter__ or
__getitem__.

Raymond

Jul 19 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.