CPython如何确定用户是否提供了可选参数?
我开始想知道CPython如何区分None作为默认参数和None作为指定参数之间的区别 例如,如果密钥不存在,dict.pop将抛出一个密钥错误。pop还接受默认返回值的参数。在本例中,我们可以将默认返回设置为None,因此:some_dict.popsome_key,None 如果要在Python中定义pop,可能需要: def popsome_键,默认值=无: 在这种情况下,将默认值定义为None或省略它都没有什么区别,但是Python可以分辨出区别。我在CPython做了一些挖掘,发现了以下实现:CPython如何确定用户是否提供了可选参数?,python,python-internals,Python,Python Internals,我开始想知道CPython如何区分None作为默认参数和None作为指定参数之间的区别 例如,如果密钥不存在,dict.pop将抛出一个密钥错误。pop还接受默认返回值的参数。在本例中,我们可以将默认返回设置为None,因此:some_dict.popsome_key,None 如果要在Python中定义pop,可能需要: def popsome_键,默认值=无: 在这种情况下,将默认值定义为None或省略它都没有什么区别,但是Python可以分辨出区别。我在CPython做了一些挖掘,发现了以
我大致能理解这是怎么回事。然而,除了在函数定义中,我似乎找不到deflt。有人向我建议,CPython没有空指针,但我可能无法识别它,因此我无法完全理解CPython如何解决用户是否提供默认值的问题。这里的执行路径是什么?如果没有传递第二个参数,则deflt是一个空指针,而不是指向None或任何其他Python对象。这不是用Python编写的函数可以做到的 您正在查看的函数没有定义默认值。您看到的是一个中间辅助函数。默认值在dict_pop_impl旁边的指令中指定:
请参见默认值:object=NULL。此注释经过预处理以生成代码,该代码查看dict.pop的参数元组并调用dict_pop_impl,如果参数元组不包含该参数的值,则生成的代码将传递默认值的空指针。如果未传递第二个参数,deflt是一个空指针,而不是指向None或任何其他Python对象。这不是用Python编写的函数可以做到的 您正在查看的函数没有定义默认值。您看到的是一个中间辅助函数。默认值在dict_pop_impl旁边的指令中指定:
请参见默认值:object=NULL。此注释经过预处理以生成代码,该代码查看dict.pop的参数元组并调用dict_pop_impl,如果参数元组不包含该参数的值,则生成的代码将传递默认值的空指针。在python逻辑中,空指针技巧只能用最后一个位置参数完成,正当否则,我看不出这是怎么回事works@roganjosh:不,我不知道你是怎么想到它会被限制在最后一个位置参数的。从那时起你就编辑了它,现在它更有意义了。为了解释我对前面注释def xa,b,c的逻辑,您提供了两个位置参数,不清楚您是否在all@roganjosh:Null默认值可以在参数诊所中使用,任何可以使用非Null默认值的地方都可以使用。现在您已经显示了默认值是在其他地方定义的,我的观点毫无意义,我的想法显然是错误的。感谢您的澄清:在python逻辑中,空指针技巧只能通过最后一个位置参数来实现,对吗?否则,我看不出这是怎么回事works@roganjosh:不,我不知道你是怎么想到它会被限制在最后一个位置参数的。从那时起你就编辑了它,现在它更有意义了。为了解释我对前面注释def xa,b,c的逻辑,您提供了两个位置参数,不清楚您是否在all@roganjosh:Null默认值可以在参数诊所中使用,任何可以使用非Null默认值的地方都可以使用。现在您已经显示了默认值是在其他地方定义的,我的观点毫无意义,我的想法显然是错误的。感谢您的澄清:
PyObject *
_PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt)
{
Py_hash_t hash;
if (((PyDictObject *)dict)->ma_used == 0) {
if (deflt) {
Py_INCREF(deflt);
return deflt;
}
_PyErr_SetKeyError(key);
return NULL;
}
if (!PyUnicode_CheckExact(key) ||
(hash = ((PyASCIIObject *) key)->hash) == -1) {
hash = PyObject_Hash(key);
if (hash == -1)
return NULL;
}
return _PyDict_Pop_KnownHash(dict, key, hash, deflt);
}
/*[clinic input]
dict.pop
key: object
default: object = NULL
/
D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
If key is not found, default is returned if given, otherwise KeyError is raised
[clinic start generated code]*/
static PyObject *
dict_pop_impl(PyDictObject *self, PyObject *key, PyObject *default_value)
/*[clinic end generated code: output=3abb47b89f24c21c input=eeebec7812190348]*/
{
return _PyDict_Pop((PyObject*)self, key, default_value);
}