Согласно документации, это не работает из-за этого:
Для пользовательских классов неявные вызовы специальных методов гарантированно будут работать правильно, только если они определены в типе объекта, а не всловарь экземпляра объекта.Такое поведение является причиной, по которой следующий код вызывает исключение:
>>> class C:
... pass
...
>>> c = C()
>>> c.__len__ = lambda: 5
>>> len(c)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'C' has no len()
https://docs.python.org/3/reference/datamodel.html#special-method-lookup
Я пробовал это на генераторе функций, который не имеет __len__
, но я заранее знал, какова его длина, затем я попытался обезьяна исправить это чем-то вроде c.__len__ = lambda: 5
, но он все время говорил, что объект генератора не имеет длины.
Это генератор:
def get_sections(loaded_config_file):
for module_file, config_parser in loaded_config_file.items():
for section in config_parser.sections():
yield section, module_file, config_parser
Я передавал генератор (который не имеет длины) этой другой функции (все же, другому генератору), которая требует итерируемой длины, вызывая len()
:
def sequence_timer(sequence, info_frequency=0):
i = 0
start = time.time()
if_counter = start
length = len(sequence)
for elem in sequence:
now = time.time()
if now - if_counter < info_frequency:
yield elem, None
else:
pi = ProgressInfo(now - start, float(i)/length)
if_counter += info_frequency
yield elem, pi
i += 1
https://github.com/arp2600/Etc/blob/60c5af803faecb2d14b5dd3041254ef00a5a79a9/etc.py
Затем при попытке добавить атрибут __len__
к get_sections
возникает ошибка:
get_sections.__len__ = lambda: calculated_length
for stuff, progress in sequence_timer( get_sections ):
section, module_file, config_parser = stuff
TypeError: object of type 'function' has no len()