为什么+(加号)可以在Python中连接两个字符串?
我正在学习以难的方式学习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
字节码指令),因为在Python 2和Python 3中都特别对待字符串。如果两个操作数都是字符串,Python会 直接
调用字符串连接函数,从而消除了需要调用特殊方法。str.__add__``+
+
Python 3
调用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); } ...
Python 2
调用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'