1

Get started

The document https://docs.python.org/3.8/reference/expressions.html#is-not means that for x is y it is true if and only if the two variables point to the same object. The object can use the id() function to check its identity (the id() function returns the mapping of the object in memory).

bytecode of is and is not

is and is not are both operators. is not is the whole, don't take x is not y as x is (not y) .

Let's take a look at the bytecodes corresponding to these two operators (based on Python 3.8):

>>> def fun():
...   x is y
...   x is not y
... 
>>> import dis
>>> dis.dis(fun)
  2           0 LOAD_GLOBAL              0 (x)
              2 LOAD_GLOBAL              1 (y)
              4 COMPARE_OP               8 (is)
              6 POP_TOP

  3           8 LOAD_GLOBAL              0 (x)
             10 LOAD_GLOBAL              1 (y)
             12 COMPARE_OP               9 (is not)
             14 POP_TOP
             16 LOAD_CONST               0 (None)
             18 RETURN_VALUE
>>>

For COMPARE_OP corresponding actions

case TARGET(COMPARE_OP): {
    PyObject *right = POP();
    PyObject *left = TOP();
    PyObject *res = cmp_outcome(tstate, oparg, left, right);
    Py_DECREF(left);
    Py_DECREF(right);
    SET_TOP(res);
    if (res == NULL)
        goto error;
    PREDICT(POP_JUMP_IF_FALSE);
    PREDICT(POP_JUMP_IF_TRUE);
    DISPATCH();
}

The meaning of this part of the code is to first take the two operands of the generation comparison from the stack, get the result of the two-number operation cmp_outcome(tstate, oparg, left, right) res top of the stack.

The relevant code of the cmp_outcome

static PyObject *
cmp_outcome(PyThreadState *tstate, int op, PyObject *v, PyObject *w)
{
    int res = 0;
    switch (op) {
    case PyCmp_IS:
        res = (v == w);
        break;
    case PyCmp_IS_NOT:
        res = (v != w);
        break;
        ...
    }
    v = res ? Py_True : Py_False;
    Py_INCREF(v);
    return v;
}

In the cmp_outcome() function, only by comparing whether the values of the two pointers are equal to determine whether they point to the same object.

Pure Python code explanation

The id() function can be used to determine the corresponding address of an object in memory, so it can also be used to determine whether two variables point to the same object:

def _is(a, b):
    return id(a) == id(b)

def _is_not(a, b):
    return id(a) != id(b)

陆安
3.2k 声望239 粉丝

宝可梦情怀粉;刀塔手残党;浴室麦霸王。