让我们来看看:
import dis
dis.dis(lambda: print_arg(**{'key': 'value'}))
6 0 LOAD_GLOBAL 0 (print_arg)
3 BUILD_MAP 1
6 LOAD_CONST 1 ('value')
9 LOAD_CONST 2 ('key')
12 STORE_MAP
13 CALL_FUNCTION_KW 0
16 RETURN_VALUE
让我们找出CALL_FUNCTION_KW
(ceval.c
)的作用:
case CALL_FUNCTION_VAR:
case CALL_FUNCTION_KW:
case CALL_FUNCTION_VAR_KW:
{
// ...
x = ext_do_call(func, &sp, flags, na, nk);
// ...
static PyObject *
ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)
{
int nstar = 0;
PyObject *callargs = NULL;
PyObject *stararg = NULL;
PyObject *kwdict = NULL;
PyObject *result = NULL;
if (flags & CALL_FLAG_KW) { // if ** is involved
kwdict = EXT_POP(*pp_stack); // get the dict passed with **
if (!PyDict_Check(kwdict)) {
PyObject *d;
d = PyDict_New(); // make a NEW dict
if (d == NULL)
goto ext_call_fail;
if (PyDict_Update(d, kwdict) != 0) { // update it with old
// .. fail ..
goto ext_call_fail;
}
Py_DECREF(kwdict);
kwdict = d; // kwdict is Now the new dict
}
}
....
result = PyObject_Call(func, callargs, kwdict); // call with new dict