Albert-Jan Roskam wrote:
>
>> If I implement __len__ in my own class, does it really have to return an
>> int? Is there no way around this (other than modifying the source code of
>> python itself ;-) It would be nice if len(Example(row, col)) would return
>> a dictionary, or a two-tuple (see code below). The strange thing is that
>> calling __len__ directly does work: Example(1, 2).__len__() returns the
>> dictionary. I always thought len() was a convenient "shorthand" for
>> __len__. I've even been reading about metaclasses (interesting, dark,
>> mysterious), thinking the answer might lie there. Note that my question is
>> not whether it's a good idea to do this, 
>
>Ah, you already know it's a bad idea...
>
>> I just find it interesting to understand how it could be done.
>
>It cannot be done without modifying the source.
>
>Here's the implementation of len() in Python 3.3:
>
>static PyObject *
>builtin_len(PyObject *self, PyObject *v)
>{
>    Py_ssize_t res;
>
>    res = PyObject_Size(v);
>    if (res < 0 && PyErr_Occurred())
>        return NULL;
>    return PyLong_FromSsize_t(res);
>}
>
>===> aha. So if I do len(Example(1, 2)) the C function "builtin_len" will be 
>called, whereas if I formulate it like Example(1, 2).__len__(), only the 
>__len__ special method of my own bogus class will be called. Interesting. I 
>was already checking if I could find __builtin__.__len__, but that's not 
>possible, probably because they're all compiled. 
>
>Thanks for your help!
>
>I did not successfully drill down further, but you can see that it may 
>signal an error or return a Python long (which I think is the same as a 
>Python int in 3.x) and that the underlying code operates on Py_size_t, so 
>you'd have to modify that code, too. Py_ssize_t is implementation dependent 
>-- on my 64-bit Linux valid lengths are in range(0, 2**63):
>
>>>> class A:
>...    def __len__(self): return self._len
>...    def __init__(self, len):
>...            self._len = len
>... 
>>>> len(A(-1))
>Traceback (most recent call last):
>  File "<stdin>", line 1, in <module>
>ValueError: __len__() should return >= 0
>>>> len(A(2**63))
>Traceback (most recent call last):
>  File "<stdin>", line 1, in <module>
>OverflowError: cannot fit 'int' into an index-sized integer
>>>> len(A(2**63-1))
>9223372036854775807
>
>
>_______________________________________________
>Tutor maillist  -  Tutor@python.org
>To unsubscribe or change subscription options:
>http://mail.python.org/mailman/listinfo/tutor
>
>
>

________________________________
From: Peter Otten <__pete...@web.de>
To: tutor@python.org 
Sent: Sunday, September 2, 2012 2:36 PM
Subject: Re: [Tutor] making len() and __len__ return a non-int
_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to