Как работает len?

Как работает len на Python?

Посмотрите на этот пример:

class INT(int):
    pass

class STR(str):

    def __len__(self):
        return INT(42)

q = STR('how').__len__()
print q, type(q)
q = len(STR('how'))
print q, type(q)

Вывод:

42 <class '__main__.INT'>
42 <type 'int'>

Как я могу справиться с этим, так что len возвращает экземпляр INT?

Ответы показывают, что единственное решение - это переопределение len

Это моя альтернативная реализация. Это не кажется очень вредным.

original_len = len
def len(o):
    l = o.__len__()
    if isinstance(l, int):
        return l
    original_len(o)

Ответ 1

Я не думаю, что вы можете, если только вы не напишете свою собственную лену. Встроенная len всегда возвращает int.

Ответ 2

Не делай этого. Вам нужно научиться, когда лучший ответ на самом деле заключается не в том, чтобы делать то, что вы пытаетесь сделать вообще. Это один из тех случаев.

Ответ 3

Вы не сможете. По крайней мере, если вы хотите, чтобы он работал с остальной частью python. См. определение len

Вызывается для внедрения встроенного функция len(). Должен вернуть длина объекта, целое число >= 0. Кроме того, объект, который не определяет отличный от нуля() метод и метод len() возвращает ноль, считается ложным в булевом контекст.

Курсив подчеркивает мой.

Ответ 4

Как говорят другие, не делайте этого. Посмотрите, как будет выглядеть использование этого класса:

length = len(s)     # the reader assumes `q` is an int.
length.in_yards()   # the reader is going WTF?!

Вместо того, чтобы нарушать ожидания читателей, почему бы вам просто не добавить другой метод:

s.length_in_yards()

P.S. Не решает этот вопрос, но если у вас есть веская причина для написания пользовательских целочисленных объектов, вас может заинтересовать __index__ специальный метод, позволяющий прямому использованию такого объекта для индексирования встроенных последовательностей.