[Tutor] Limitation of int() in converting strings

Oscar Benjamin oscar.j.benjamin at gmail.com
Thu Jan 3 15:33:54 CET 2013


On 2 January 2013 17:59, Alan Gauld <alan.gauld at btinternet.com> wrote:
> On 01/02/2013 11:41 AM, Steven D'Aprano wrote:
>
>[SNIP]
>> But __index__ is a special method that converts to int without rounding
>> or truncating, intended only for types that emulate ints but not other
>> numeric types:
>
>
> And this was the new bit I didn't know about.
>
> [SNIP]
>>>> help(int.__index__)
> Help on wrapper_descriptor:
>
> __index__(...)
>     x[y:z] <==> x[y.__index__():z.__index__()]
>
>
> Bingo! Although still doesn't anything explicitly about the need for an
> integer!

The operator.index builtin checks that an int/long is returned. The
same is true of the underlying C-API that is used internally by
indexable sequences (list, tuple, etc.).

$ python
Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit
(Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import operator
>>> class A(object):
...     def __index__(self):
...         return 4.5
...
>>> a = A()
>>> a.__index__()
4.5
>>> operator.index(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __index__ returned non-(int,long) (type float)
>>> b = [1,2,3]
>>> b[a]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __index__ returned non-(int,long) (type float)

You only need to know about this feature if you are implementing a
custom integer type or a custom sequence type (both of which are
things that most Python users will never do). This particular special
method is probably only really documented in the PEP:
http://www.python.org/dev/peps/pep-0357/

For my purposes, the important thing is that the method is only
supposed to be implemented on types that always exactly represent
integers, so it is not usable for converting e.g. floats to integers.


Oscar


More information about the Tutor mailing list