set.issubset 和set.issuperset 的implementation 坚持首先建立一个论点:
static PyObject *
set_issubset(PySetObject *so, PyObject *other)
{
setentry *entry;
Py_ssize_t pos = 0;
int rv;
if (!PyAnySet_Check(other)) {
PyObject *tmp, *result;
tmp = make_new_set(&PySet_Type, other);
if (tmp == NULL)
return NULL;
result = set_issubset(so, tmp);
Py_DECREF(tmp);
return result;
}
if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
Py_RETURN_FALSE;
while (set_next(so, &pos, &entry)) {
rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
if (rv < 0)
return NULL;
if (!rv)
Py_RETURN_FALSE;
}
Py_RETURN_TRUE;
}
PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
static PyObject *
set_issuperset(PySetObject *so, PyObject *other)
{
PyObject *tmp, *result;
if (!PyAnySet_Check(other)) {
tmp = make_new_set(&PySet_Type, other);
if (tmp == NULL)
return NULL;
result = set_issuperset(so, tmp);
Py_DECREF(tmp);
return result;
}
return set_issubset((PySetObject *)other, (PyObject *)so);
}
PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
issuperset 从参数中创建一个集合,然后调用other.issubset(self)。 (issubset 也坚持使用一个集合作为它的参数,但它得到了一个,所以在这种情况下不需要转换。)他们可以很容易地向issuperset 添加一个代码路径来处理非集合没有集合转换的参数,但他们没有。
我怀疑其原因可能是在调用 {1}.issuperset([2, [3]]) 时抛出错误,其中参数包含不可散列的元素。但是,也可能没有人费心对其进行优化。在Python issue tracker 中搜索issuperset 会发现关于优化issuperset 的0 个问题,甚至没有关闭的问题。令人惊讶的是,closed issue 对 issubset 进行了更困难的优化,但虽然它会导致类似的异常行为变化,但关于该问题的回复都没有说明这一点。