|
|
1
9
你试图做的事情是有道理的,但Python内部正在发生一些邪恶的事情。
我不熟悉Python的内部,但似乎一个对象的“next”方法被缓存在
你可以通过保留原始的next函数并显式地包装它来解决这个问题:
不 |
|
|
2
6
CPython在很多地方都采取了令人惊讶的捷径 例子 物业。这就是其中一个地方。
>>> instance = DynamicNext() >>> next(instance) ⦠TypeError: DynamicNext object is not an iterator >>>
现在,深入研究CPython源代码(来自2.7.2),以下是
下面是PyIter_Check的实现:
>>> instance.__class__.__flags__ & 1L<<17 != 0 True
在Python中,这一行大致(粗略!)相当于
>>> type(instance) __main__.DynamicNext >>> hasattr(type(instance), "next") False
这显然是失败的,因为
当创建CPython类型时(即解释器首次计算
现在,正如Glenn指出的那样,这几乎可以肯定是CPython中的一个错误。特别是考虑到只有当被测试的对象不可迭代或动态分配时,纠正它才会影响性能
编辑
:经过一点挖掘,修复就不会这么简单了,因为至少部分代码假设,如果
所以!这就是为什么当你试图迭代一个动态分配的新型实例时,会发生令人惊讶的事情
|
|
|
3
4
所以解决办法就是回去
虽然我不明白为什么不
|
|
|
4
3
编辑:现在有两种方法。一次,monkey修补包装好的迭代器,第二次,kitty包装迭代器。
这两种方法都适用于新旧风格的类。 |