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

发布于 2021-01-29 17:33:39

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

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

解释为什么将两个字符串we在一起并用+组成一个更长的字符串。

甚至我都知道它可以工作,但是我不明白为什么以及如何做?请帮我。

关注者
0
被浏览
140
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    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'
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看