前言
我正在处理一个测试,其中涉及到嵌套可迭代对象(所谓的嵌套可迭代对象是指只包含可迭代对象作为元素的可迭代对象)。
假设我们有以下测试级联:
from itertools import tee
from typing import (Any,
Iterable)
def foo(nested_iterable: Iterable[Iterable[Any]]) -> Any:
...
def test_foo(nested_iterable: Iterable[Iterable[Any]]) -> None:
original, target = tee(nested_iterable) # this doesn't copy iterators elements
result = foo(target)
assert is_contract_satisfied(result, original)
def is_contract_satisfied(result: Any,
original: Iterable[Iterable[Any]]) -> bool:
...
例如,
foo
可能是一个简单的标识函数。def foo(nested_iterable: Iterable[Iterable[Any]]) -> Iterable[Iterable[Any]]:
return nested_iterable
合同只是检查扁平化的可迭代对象是否具有相同的元素。
from itertools import (chain,
starmap,
zip_longest)
from operator import eq
...
flatten = chain.from_iterable
def is_contract_satisfied(result: Iterable[Iterable[Any]],
original: Iterable[Iterable[Any]]) -> bool:
return all(starmap(eq,
zip_longest(flatten(result), flatten(original),
# we're assuming that ``object()``
# will create some unique object
# not presented in any of arguments
fillvalue=object())))
但是,如果nested_iterable
中的某些元素是一个迭代器,那么当使用tee
进行浅拷贝时,它可能会被耗尽。也就是说,对于给定的foo
和is_contract_satisfied
语句而言,它们并不是深层次的拷贝。
>>> test_foo([iter(range(10))])
导致可预测的
Traceback (most recent call last):
...
test_foo([iter(range(10))])
File "...", line 19, in test_foo
assert is_contract_satisfied(result, original)
AssertionError
问题
如何深度复制任意嵌套可迭代对象?
注意
我知道有 copy.deepcopy
函数,但它对文件对象无效。