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);
...
Эта оптимизация была в Python когда-либо с 2004 года из issue980695:
... в прилагаемом патче ceval.с специальные футляры сложение двух строк (таким же образом, как это специальные футляры сложения двух целых чисел уже)
Но обратите внимание, что основной целью было больше, чем устранение специального поиска атрибута.
Для чего это стоит, 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) из фрагментов кода выше будет ложным:
>>> class STR(str):
... def __add__(self, other):
... print('calling __add__')
... return super().__add__(other)
...
>>> STR('abc') + STR('def')
calling __add__
'abcdef'
Почему это вас удивляет, а не факт, что '+' может добавить два числа? Именно так Guido определил оператор '+' Python. – user2357112
* Объясните, почему добавление двух строк w и e с + делает более длинную строку. * - Что еще вы ожидаете? – thefourtheye
Подождите, пока вы доберетесь до ''Hello' * 3' –