range() is not the best way to check range?

A

Alex Martelli

Paul Boddie said:
A subclass of list is probably a bad idea in hindsight, due to various
probable requirements of it actually needing to be a list with all its
contents, whereas we wanted to avoid having anything like a list around
until the contents of this "lazy list" were required by the program. If
we really wanted to subclass something, we could consider subclassing
the slice class/type, but that isn't subclassable in today's Python for
some reason, and it doesn't really provide anything substantial,
anyway. However, Python being the language it is, an appropriately
behaving class is quite easily written from scratch.

Nevertheless, that class will still need to implement every single
method of the list type; making it a subclass of list has some advantage
in that every such implementation of a method can basically fill the
real list, self.__class__=list, and leave all the rest, forevermore
(explicitly here, implicitly in the future), to class list. Performance
should be much better than by working off semi-deprecated UserList.

A "hook method" __mutator__ (ideally called _before_ in this case), as I
was proposing (for 2.6 or later), would make such approaches way easier
and handier (and would help with most use cases I can think of for
subclassing list, dict or set).


Alex
 
A

Antoon Pardon

A subclass of list is probably a bad idea in hindsight, due to various
probable requirements of it actually needing to be a list with all its
contents, whereas we wanted to avoid having anything like a list around
until the contents of this "lazy list" were required by the program. If
we really wanted to subclass something, we could consider subclassing
the slice class/type, but that isn't subclassable in today's Python for
some reason, and it doesn't really provide anything substantial,
anyway. However, Python being the language it is, an appropriately
behaving class is quite easily written from scratch.

Except that if you write your own class from scratch, you can't use
it as a slice. For a language that is supposed to be about duck typing
I find it strange that if I make my own class with a start, stop and
step attribute, that python barfs on it when I want to use it as a
slice.
.... def __init__(self, start = None, stop = None, step = None):
.... self.start = start
.... self.stop = stop
.... self.step = step
....
lst = range(20)
s1 = slice(3,13)
s2 = sl(3,13)
s1.start 3
s2.start 3
s1.stop 13
s2.stop 13
s1.step
s2.step
lst[s1] [3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
lst[s2]
Traceback (most recent call last):
 
P

Paul Boddie

[Subclasses of list or slice for ranges]
Except that if you write your own class from scratch, you can't use
it as a slice. For a language that is supposed to be about duck typing
I find it strange that if I make my own class with a start, stop and
step attribute, that python barfs on it when I want to use it as a
slice.

[s2 has start, stop, step...]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: list indices must be integers

In fact, the duck typing seems only to really work outside the
interpreter and the various accompanying built-in classes. Consider a
class similar to the one you defined with the name myslice (for
clarity) and with the apparently necessary indices method; consider it
used as follows:
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: list indices must be integers

Here, we start to believe that only traditional index or slice notation
will work. However, we did come across the built-in slice class before;
consider this:
[1, 3]

Regardless of whether myslice inherits from object or not, there's no
persuading the interpreter that it is a genuine slice, and remember
that we can't subclass slice (for some reason unknown). So, it would
appear that the interpreter really wants instances from some specific
set of types (presumably discoverable by looking at list_subscript in
listobject.c) rather than some objects conforming to some interface or
protocol, and perhaps it is implemented this way for performance
reasons.

In any case, in the core of Python some types/classes are more equal
than others, and for whatever reason the duck typing breaks down - a
case of "malbik endar" [1] that you just have to be aware of, I
suppose.

Paul

[1] http://www.sciamanna.com/island/pop/2004_07_13/280_malbik_endar.htm
 
S

Steve Holden

Paul Boddie wrote:
[...]
Regardless of whether myslice inherits from object or not, there's no
persuading the interpreter that it is a genuine slice, and remember
that we can't subclass slice (for some reason unknown). So, it would
appear that the interpreter really wants instances from some specific
set of types (presumably discoverable by looking at list_subscript in
listobject.c) rather than some objects conforming to some interface or
protocol, and perhaps it is implemented this way for performance
reasons.

In any case, in the core of Python some types/classes are more equal
than others, and for whatever reason the duck typing breaks down - a
case of "malbik endar" [1] that you just have to be aware of, I
suppose.
... pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
type 'slice' is not an acceptable base type
Indeed.

regards
Steve
 
A

Antoon Pardon

Regardless of whether myslice inherits from object or not, there's no
persuading the interpreter that it is a genuine slice, and remember
that we can't subclass slice (for some reason unknown). So, it would
appear that the interpreter really wants instances from some specific
set of types (presumably discoverable by looking at list_subscript in
listobject.c) rather than some objects conforming to some interface or
protocol, and perhaps it is implemented this way for performance
reasons.

In any case, in the core of Python some types/classes are more equal
than others, and for whatever reason the duck typing breaks down - a
case of "malbik endar" [1] that you just have to be aware of, I
suppose.

Is there any chance this will iever change?

Is there any chance the start:stop:step notation will ever
be considered an atom?
 
P

Paul Boddie

Antoon said:
Except that if you write your own class from scratch, you can't use
it as a slice.

Correct, but we were actually discussing subclassing built-in classes
for use as a replacement for range/xrange. :)

It may be "hard work" writing all those methods in a totally new
range/xrange class, but passing objects of that class around should
prove satisfactory for the use of most programs. I personally doubt
that it is that much hard work, especially if you stick to a reasonable
selection of list capabilities, for example, rather than attempting to
emulate support for every dodgy trick available to the programmer in
the modern CPython arsenal.
For a language that is supposed to be about duck typing
I find it strange that if I make my own class with a start, stop and
step attribute, that python barfs on it when I want to use it as a
slice.

Yes, my post showed this and gave a reference to where in the CPython
source code the tests for specific types are performed.

Paul
 
A

Antoon Pardon

Correct, but we were actually discussing subclassing built-in classes
for use as a replacement for range/xrange. :)

I think a slice could be very usefull for that.

To me it feel very natural that a slice would be iterable and
could be used in a form like:

for i in slice(10,20):

or if the slice notation would be usable

for i in (10:20):

And why not make a slice indexable too?


Whether slices really are the tool to use here or not
I don know for sure. But the problem is, that you
can't easily experiment with this idea because slices
are not subclassable.
It may be "hard work" writing all those methods in a totally new
range/xrange class, but passing objects of that class around should
prove satisfactory for the use of most programs.

But the parameters you will have to give such a class are the same
you have to pass to a slice. IMO that means that you should at least
consider giving slices this functionality. At least it should be
easy to convert from one to the other and back.
 

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,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top