jos*_*ith 18 python contains python-2.7
我__contains__前几天第一次在类上实现了这个方法,行为不是我的预期.我怀疑in操作员有些微妙,我不明白,我希望有人可以启发我.
在我看来,in操作符不是简单地包装对象的__contains__方法,但它也试图强制输出__contains__为boolean.例如,考虑一下这门课程
class Dummy(object):
def __contains__(self, val):
# Don't perform comparison, just return a list as
# an example.
return [False, False]
Run Code Online (Sandbox Code Playgroud)
在in运营商和对直接调用__contains__方法返回非常不同的输出:
>>> dum = Dummy()
>>> 7 in dum
True
>>> dum.__contains__(7)
[False, False]
Run Code Online (Sandbox Code Playgroud)
再次,它看起来像是in在调用__contains__,然后将结果强制转换为bool.我无法在任何地方找到这种行为,除了__contains__ 文档说的__contains__应该只返回True或者False.
我很高兴遵循这个惯例,但有人可以告诉我in和之间的确切关系__contains__吗?
我决定选择@ eli-korvigo的答案,但是每个人都应该看看@ ashwini-chaudhary 关于这个bug的评论.
Eli*_*igo 13
使用来源,卢克!
让我们来看一下in运营商的实施情况
>>> import dis
>>> class test(object):
... def __contains__(self, other):
... return True
>>> def in_():
... return 1 in test()
>>> dis.dis(in_)
2 0 LOAD_CONST 1 (1)
3 LOAD_GLOBAL 0 (test)
6 CALL_FUNCTION 0 (0 positional, 0 keyword pair)
9 COMPARE_OP 6 (in)
12 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
如您所见,in操作员成为COMPARE_OP虚拟机指令.你可以在ceval.c中找到它
TARGET(COMPARE_OP)
w = POP();
v = TOP();
x = cmp_outcome(oparg, v, w);
Py_DECREF(v);
Py_DECREF(w);
SET_TOP(x);
if (x == NULL) break;
PREDICT(POP_JUMP_IF_FALSE);
PREDICT(POP_JUMP_IF_TRUE);
DISPATCH();
Run Code Online (Sandbox Code Playgroud)
看看其中一个开关 cmp_outcome()
case PyCmp_IN:
res = PySequence_Contains(w, v);
if (res < 0)
return NULL;
break;
Run Code Online (Sandbox Code Playgroud)
在这里,我们有PySequence_Contains电话
int
PySequence_Contains(PyObject *seq, PyObject *ob)
{
Py_ssize_t result;
PySequenceMethods *sqm = seq->ob_type->tp_as_sequence;
if (sqm != NULL && sqm->sq_contains != NULL)
return (*sqm->sq_contains)(seq, ob);
result = _PySequence_IterSearch(seq, ob, PY_ITERSEARCH_CONTAINS);
return Py_SAFE_DOWNCAST(result, Py_ssize_t, int);
}
Run Code Online (Sandbox Code Playgroud)
这总是返回一个int(布尔值).
PS
感谢的Martijn Pieters的提供的方式查找执行in操作.
在Python中,__contains__它的编写__contains__应该返回True或写入False.
如果返回值不是布尔值,则将其转换为布尔值.这是证明:
class MyValue:
def __bool__(self):
print("__bool__ function ran")
return True
class Dummy:
def __contains__(self, val):
return MyValue()
Run Code Online (Sandbox Code Playgroud)
现在写在shell中:
>>> dum = Dummy()
>>> 7 in dum
__bool__ function ran
True
Run Code Online (Sandbox Code Playgroud)
与bool()非空目录的回报True.
编辑:
这是唯一的文档__contains__,如果你真的想看到精确的关系,你应该考虑查看源代码,虽然我不确定究竟在哪里,但它已经得到了答案.在比较文档中写道:
但是,这些方法可以返回任何值,因此如果在布尔上下文中使用比较运算符(例如,在
if语句的条件下),Python将对值调用bool()以确定结果是true还是false.
所以你可以猜测它与它相似__contains__.
| 归档时间: |
|
| 查看次数: |
8977 次 |
| 最近记录: |