*迭代对象,并将其元素用作参数。
**迭代对象的,
keys并使用
__getitem__(相当于括号表示法)来获取键值对。要进行定制
*,只需使您的对象可迭代,并进行定制
**,使您的对象成为映射:
class MyIterable(object): def __iter__(self): return iter([1, 2, 3])class MyMapping(collections.Mapping): def __iter__(self): return iter('123') def __getitem__(self, item): return int(item) def __len__(self): return 3如果您想要
*并且
**做上面描述的 以外的
事情,您就不能。我没有该声明的文档参考(因为查找“可以执行此操作”的文档比“不能执行此操作”要容易得多),但是我有一个源引文。字节码解释器在
Pyeval_evalframeEx调用中循环,
ext_do_call以使用
*或
**参数实现函数调用。
ext_do_call包含以下代码:
if (!PyDict_Check(kwdict)) { PyObject *d; d = PyDict_New(); if (d == NULL) goto ext_call_fail; if (PyDict_Update(d, kwdict) != 0) {如果
**参数不是dict,则创建一个dict并执行普通操作
update以从关键字参数中对其进行初始化(除非该方法
PyDict_Update不接受键值对列表)。因此,您不能
**与实现映射协议分开进行自定义。
同样,对于
*参数,
ext_do_call执行
if (!PyTuple_Check(stararg)) { PyObject *t = NULL; t = PySequence_Tuple(stararg);等同于
tuple(args)。因此,您不能
*与普通迭代分开进行自定义。
如果
f(*thing)并且
f(*iter(thing))做了不同的事情,那将令人非常困惑。在任何情况下,
*并且
**是函数调用语法的一部分,而不是独立的运营商,所以他们定制(如果可能)将是可调用的工作,而不是争论的。我想可能会有用例允许可调用对象自定义它们,也许
dict像这样传递子类
defaultdict…



