Skip to main content
 首页 » 编程设计

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

2025年05月04日13txw1958

我正在以艰难的方式学习 Learn Python。

w = "This is the left side of..." 
e = "a string with a right side." 
print w + e 

解释为什么用 + 添加两个字符串 w 和 e 会得到一个更长的字符串。

即使我知道它可以工作,但我不明白为什么以及如何?请帮助我。

请您参考如下方法:

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

虽然 __add__ 是真的特殊方法通常用于实现 + 运算符,+ ( BINARY_ADD bytecode instruction ) 不调用 str.__add__ 因为 + 在 Python 2 和 Python 3 中都对字符串进行特殊处理。如果 + 的两个操作数都是字符串,Python 会直接调用字符串连接函数,从而消除了调用特殊方法的需要。

Python 3 调用 unicode_concatenate ( source code ):

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); 
    } 
    ... 

Python 2 调用 string_concatenate ( source code ):

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 :

... in the attached patch ceval.c special-cases addition of two strings (in the same way as it special-cases addition of two integers already)

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


就其值(value)而言,str.__add__ 仍然按预期工作:

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

Python会调用str子类的__add__方法,因为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'