我正在学习如何学习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
字节码指令)也不能打电话str.__add__
,因为+
对待两者的Python 2和Python 3 Python的专门弦乐器调用字符串连接功能,直接如果两个操作数+
都是字符串,从而消除了需要调用特殊方法.
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'