gpt4 book ai didi

python - 如何将 __len__ 添加到数据类型定义中没有 __len__ 的对象?

转载 作者:太空狗 更新时间:2023-10-30 02:52:05 24 4
gpt4 key购买 nike

根据文档,这不起作用,因为:

For custom classes, implicit invocations of special methods are only guaranteed to work correctly if defined on an object’s type, not in the object’s instance dictionary. That behaviour is the reason why the following code raises an exception:

>>> 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: 'function' 类型的对象没有 len()

最佳答案

您不能将它添加到现有对象中,因此请创建您自己的包装类,该类具有您控制的类级别定义:

class KnownLengthIterator:
def __init__(self, it, length):
self.it = it
self.length = int(length)

def __len__(self):
return self.length

def __iter__(self):
yield from self.it

现在您只需将您的无效尝试更改为设置长度:

get_sections.__len__ = lambda: calculated_length

一个有效的重新包装,使 get_sections 继续成为一个有效的生成器(yield from 将所有迭代行为委托(delegate)给包装的生成器),同时也暴露了一个长度:

get_sections = KnownLengthIterator(get_sections, calculated_length)

没有其他代码需要更改。

关于python - 如何将 __len__ 添加到数据类型定义中没有 __len__ 的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54262704/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com