gpt4 book ai didi

python - 更改 *splat 和 **splatty-splat 运算符对我的对象执行的操作

转载 作者:太空狗 更新时间:2023-10-29 17:42:49 25 4
gpt4 key购买 nike

如何覆盖解包语法*obj**obj的结果?

例如,您能否以某种方式创建一个行为如下的对象 thing:

>>> [*thing]
['a', 'b', 'c']
>>> [x for x in thing]
['d', 'e', 'f']
>>> {**thing}
{'hello world': 'I am a potato!!'}

注意:通过 __iter__(“for x in thing”)的迭代从 *splat 解包中返回不同的元素。

我查看了operator.muloperator.pow,但这些函数只涉及两个操作数的用法,比如a*ba**b,并且似乎与 splat 操作无关。

最佳答案

* 迭代对象并将其元素用作参数。 ** 遍历对象的 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) {

如果 ** 参数不是字典,则创建一个字典并执行普通的 update 以从关键字参数初始化它(除了 PyDict_Update 不接受键值对列表)。因此,您不能在实现映射协议(protocol)之外单独自定义 **

类似地,对于 * 参数,ext_do_call 执行

        if (!PyTuple_Check(stararg)) {
PyObject *t = NULL;
t = PySequence_Tuple(stararg);

相当于tuple(args)。因此,您不能从普通迭代中单独自定义 *

如果 f(*thing)f(*iter(thing)) 做了不同的事情,那将会非常困惑。在任何情况下,*** 都是函数调用语法的一部分,而不是单独的运算符,因此自定义它们(如果可能)将是可调用对象的工作,而不是参数的工作.我想可能会有允许可调用者自定义它们的用例,也许可以传递 dict 子类,如 defaultdict 通过...

关于python - 更改 *splat 和 **splatty-splat 运算符对我的对象执行的操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22365847/

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