itertools.islice 与 functools.partial 一起使用时引发 ValueError
itertools.islice raise a ValueError when used with functools.partial
考虑以下 python 会话 (3.6.1):
>>> from itertools import islice
>>> l = [i for i in range(10)]
>>> islice(l, 0, 1)
<itertools.islice object at 0x7f87c9293638>
>>> (lambda it: islice(it, 0, 1))(l)
<itertools.islice object at 0x7fe35ab40408>
这里没有什么出乎意料的。现在,functools.partial
:
>>> from functools import partial
>>> partial(islice, 0, 1)(l)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Stop argument for islice() must be None or an integer: 0 <= x <= sys.maxsize.
partial
似乎以非常意外的方式干扰了 islice
行为。
这种行为背后的基本原理是什么?这是因为 islice 不处理关键字参数,like str.split few versions ago ?
问题在于:
partial(islice, 0, 1)
转换为:
islice(0, 1, l)
失败是因为 islice
期望其参数按特定顺序排列。然而,以这种方式使用 partial
会导致参数以错误的顺序传递。如果将虚拟函数传递给 partial
:
,您可以自己看到这一点
>>> def func(*args):
print('args:', args)
>>> partial(func, 0, 1)(l)
args: (0, 1, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
并且因为您不能将关键字参数与 islice
一起使用来更改参数传递的顺序,所以您不能在此处使用 partial
。正如@Martijn Pieters 所说,只需使用普通函数或 lambda
:
>>> from itertools import islice
>>> from functools import partial
>>>
>>> f = lambda l: islice(l, 0, 1)
>>> l = [i for i in range(10)]
>>> list(f(l))
[0]
位置参数在其他位置参数之后传递。所以 partial(islice, 0, 1)(l)
和 islice(0, 1, l)
是一样的,这是行不通的。
您不能使用部分函数以不同的顺序传入参数;只有关键字参数才允许这样做。由于 islice
没有关键字参数,因此您 不能在此处使用 partial()
。
您唯一的选择是使用 lambda
。
考虑以下 python 会话 (3.6.1):
>>> from itertools import islice
>>> l = [i for i in range(10)]
>>> islice(l, 0, 1)
<itertools.islice object at 0x7f87c9293638>
>>> (lambda it: islice(it, 0, 1))(l)
<itertools.islice object at 0x7fe35ab40408>
这里没有什么出乎意料的。现在,functools.partial
:
>>> from functools import partial
>>> partial(islice, 0, 1)(l)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Stop argument for islice() must be None or an integer: 0 <= x <= sys.maxsize.
partial
似乎以非常意外的方式干扰了 islice
行为。
这种行为背后的基本原理是什么?这是因为 islice 不处理关键字参数,like str.split few versions ago ?
问题在于:
partial(islice, 0, 1)
转换为:
islice(0, 1, l)
失败是因为 islice
期望其参数按特定顺序排列。然而,以这种方式使用 partial
会导致参数以错误的顺序传递。如果将虚拟函数传递给 partial
:
>>> def func(*args):
print('args:', args)
>>> partial(func, 0, 1)(l)
args: (0, 1, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
并且因为您不能将关键字参数与 islice
一起使用来更改参数传递的顺序,所以您不能在此处使用 partial
。正如@Martijn Pieters 所说,只需使用普通函数或 lambda
:
>>> from itertools import islice
>>> from functools import partial
>>>
>>> f = lambda l: islice(l, 0, 1)
>>> l = [i for i in range(10)]
>>> list(f(l))
[0]
位置参数在其他位置参数之后传递。所以 partial(islice, 0, 1)(l)
和 islice(0, 1, l)
是一样的,这是行不通的。
您不能使用部分函数以不同的顺序传入参数;只有关键字参数才允许这样做。由于 islice
没有关键字参数,因此您 不能在此处使用 partial()
。
您唯一的选择是使用 lambda
。