您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

为什么+(加号)可以在Python中连接两个字符串?

为什么+(加号)可以在Python中连接两个字符串?

Python用于+连接字符串,因为这是Python的核心开发人员定义该运算符的方式。

的确,__add__通常使用特殊方法来实现该+运算符,但不会 调用+BINARY_ADD字节码指令),因为在Python 2和Python 3中都特别对待字符串。如果两个操作数都是字符串,Python会 直接 调用字符串连接函数,从而消除了需要调用特殊方法+

调用unicode_concatenate源代码):

TARGET(BINARY_ADD) {
    PyObject *right = POP();
    PyObject *left = TOP();
    PyObject *sum;
    if (PyUnicode_CheckExact(left) &&
             PyUnicode_CheckExact(right)) {
        sum = unicode_concatenate(left, right, f, next_instr);
        /* unicode_concatenate consumed the ref to v */
    }
    else {
        sum = PyNumber_Add(left, right);
        Py_DECREF(left);
    }
    ...

调用string_concatenate源代码):

case BINARY_ADD:
    w = POP();
    v = TOP();
    if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
        /* INLINE: int + int */
        register long a, b, i;
        a = PyInt_AS_LONG(v);
        b = PyInt_AS_LONG(w);
        /* cast to avoid undefined behavIoUr
           on overflow */
        i = (long)((unsigned long)a + b);
        if ((i^a) < 0 && (i^b) < 0)
            goto slow_add;
        x = PyInt_FromLong(i);
    }
    else if (PyString_CheckExact(v) &&
             PyString_CheckExact(w)) {
        x = string_concatenate(v, w, f, next_instr);
        /* string_concatenate consumed the ref to v */
        goto skip_decref_vx;
    }
    else {
      slow_add:
        x = PyNumber_Add(v, w);

    ...

自2004年以来,就一直在Python中进行这种优化。从issue980695

…在随附的补丁程序 ceval.c中 ,对两个字符串进行特殊情况的加法 运算 (与对特殊情况的两个整数进行加法 运算 的方式相同)

但是请注意,主要目标是消除特殊属性查找。

对于它的价值,str.__add__仍然可以按预期工作:

>>> w.__add__(e)
'This is the left side of...a string with a right side.'

并且Python将调用__add__的子类的方法str,因为上述代码段中的PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)(或PyString_CheckExact(v) && PyString_CheckExact(w)在Python 2中为)将为false:

>>> class STR(str):
...     def __add__(self, other):
...         print('calling __add__')
...         return super().__add__(other)
... 
>>> STR('abc') + STR('def')
calling __add__
'abcdef'
python 2022/1/1 18:45:30 有593人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶