I was wondering if the following two "if" statements compile down to
the same bytecode for a standard Dictionary type:
m = {"foo": 1, "blah": 2}
if "foo" in m:
print "sweet"
if m.has_key("foo"):
print "dude"
To answer the question you actually asked, you can use dis.dis:
py> def f1(s, m):
.... if s in m:
.... pass
....
py> def f2(s, m):
.... if m.has_key(s):
.... pass
....
py> import dis
py> dis.dis(f1)
2 0 LOAD_FAST 0 (s)
3 LOAD_FAST 1 (m)
6 COMPARE_OP 6 (in)
9 JUMP_IF_FALSE 4 (to 16)
12 POP_TOP
3 13 JUMP_FORWARD 1 (to 17) 20 RETURN_VALUE
py> dis.dis(f2)
2 0 LOAD_FAST 1 (m)
3 LOAD_ATTR 1 (has_key)
6 LOAD_FAST 0 (s)
9 CALL_FUNCTION 1
12 JUMP_IF_FALSE 4 (to 19)
15 POP_TOP
3 16 JUMP_FORWARD 1 (to 20) 23 RETURN_VALUE
Note that in the *bytecode*, f1 uses COMPARE_OP, while f2 uses LOAD_ATTR
and CALL_FUNCTION. So no, the bytecode is different.
If the question you meant to as was "Do Python's builtin dicts use the
same code for 'in' and 'has_key'?", you can check dictobject.c:
static PyMethodDef mapp_methods[] = {
{"__contains__",(PyCFunction)dict_has_key, METH_O | METH_COEXIST,
contains__doc__},
...
{"has_key", (PyCFunction)dict_has_key, METH_O,
has_key__doc__},
...
};
Note that both __contains__ and has_key are mapped to dict_has_key. So
yes, the same C code will be executed in both cases[1].
STeVe
[1] modulo the different lookup paths to find these methods