【发布时间】:2019-11-29 10:45:49
【问题描述】:
我开始想知道 CPython 如何区分 None 作为默认参数和 None 作为指定参数。
例如,如果密钥不存在,dict.pop() 将抛出 KeyError。 .pop() 还接受默认返回值的参数。在本例中,我们可以将默认返回设置为None,因此:some_dict.pop(some_key, None)
如果您要在 Python 中定义 pop,您可能会有:
def pop(some_key, default=None):
在这种情况下,您将default 定义为None 还是将其省略都不会有什么不同,但Python 可以区分。我在CPython中做了一些挖掘,发现了dict.pop()的实现:
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);
}
我可以大致了解它是如何工作的。但是,我似乎无法在该函数定义中找到 deflt(有人建议我 CPython 有一个 None 的空指针,但我可能无法识别它),所以我不太明白如何CPython 解决了用户是否提供了默认值的问题。这里的执行路径是什么?
【问题讨论】: