Python用于
+连接字符串,因为这是Python的核心开发人员定义该运算符的方式。
的确,
__add__通常使用特殊方法来实现该
+运算符,但
不会
调用
+(
BINARY_ADD字节码指令),因为在Python 2和Python 3中都特别对待字符串。如果两个操作数都是字符串,Python会 直接
调用字符串连接函数,从而消除了需要调用特殊方法。
str.__add__``+
+
Python 3
调用
unipre_concatenate(源代码):
TARGET(BINARY_ADD) { PyObject *right = POP(); PyObject *left = TOP(); PyObject *sum; if (PyUnipre_CheckExact(left) && PyUnipre_CheckExact(right)) { sum = unipre_concatenate(left, right, f, next_instr); } 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)) { register long a, b, i; a = PyInt_AS_LONG(v); b = PyInt_AS_LONG(w); 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); 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,因为上述代码段中的
PyUnipre_CheckExact(left) &&PyUnipre_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'


