String python str内置和字符串插值,有人能解释一下发生了什么吗?

String python str内置和字符串插值,有人能解释一下发生了什么吗?,string,python-2.7,unicode,built-in,string-interpolation,String,Python 2.7,Unicode,Built In,String Interpolation,考虑以下简单类: >>> class W(object): ... def __str__(self): ... print "entering __str__" ... return u"a" ... w = W() 请注意: 执行\uuu str\uu方法时,将打印一条消息 \uuuu str\uuu方法返回恶意unicode值 在下面的doctests中,我们将使用类w的相同且唯一的实例w 现在,首先考虑这个相对直观的DOCTR

考虑以下简单类:

>>> class W(object):
...     def __str__(self):
...         print "entering __str__"
...         return u"a"
...  w = W()
请注意:

  • 执行
    \uuu str\uu
    方法时,将打印一条消息
  • \uuuu str\uuu
    方法返回恶意unicode值
  • 在下面的doctests中,我们将使用类
    w
    的相同且唯一的实例
    w
  • 现在,首先考虑这个相对直观的DOCTREST会话:

    >>> u"%s" % w
    entering __str__
    u'a'
    
    >>> w.__str__()
    entering __str__
    u'a'
    
    >>> "%s" % w
    entering __str__
    entering __str__
    u'a'
    
    >>> str(w)
    entering __str__
    'a'
    
    WTF博士测试会话:

    >>> u"%s" % w
    entering __str__
    u'a'
    
    >>> w.__str__()
    entering __str__
    u'a'
    
    >>> "%s" % w
    entering __str__
    entering __str__
    u'a'
    
    >>> str(w)
    entering __str__
    'a'
    
    你能否解释一下原因:

  • 在第一个示例中,函数
    \uuu str\uu
    被调用了两次
  • 调用
    w.\uuu str\uuu()
    提供的输出与
    str(w)
    不同

  • 感谢您对这些主题的见解。。。欢迎任何关于文档(或更好的……代码!)的指针。

    让我们看看这里发生了什么。首先,我们需要找出%运算符的操作代码:

    >>> import dis
    >>> def modop():
    ...  '%s' % w
    ...
    >>> dis.dis(modop)
      2           0 LOAD_CONST               1 ('%s')
                  3 LOAD_GLOBAL              0 (w)
                  6 BINARY_MODULO
                  7 POP_TOP
                  8 LOAD_CONST               0 (None)
                 11 RETURN_VALUE
    
    好的,我们需要检查ceval.c中的二进制_模操作码,看看python在做什么。以下是源代码(Python-2.7.6\Python\ceval.c):

    在Python源代码中搜索“PyString_Format”,我们发现函数是在Python-2.7.6\Objects\stringobject.c中定义的。在4447行附近,我们发现:

    #ifdef Py_USING_UNICODE
                    if (PyUnicode_Check(v)) {
                        fmt = fmt_start;
                        argidx = argidx_start;
                        goto unicode;
                    }
    #endif
                    temp = _PyObject_Str(v);
    #ifdef Py_USING_UNICODE
                    if (temp != NULL && PyUnicode_Check(temp)) {
                        Py_DECREF(temp);
                        fmt = fmt_start;
                        argidx = argidx_start;
                        goto unicode;
                    }
    #endif
    
    goto跳转到unicode:,然后调用

    v = PyUnicode_Format(format, args);
    
    那么,解释一下

    >>> "%s" % w
    entering __str__
    entering __str__
    u'a'
    
    我的最佳选择是
    PyUnicode\u Check
    必须调用
    \u str\u
    来确定对象的字符串表示形式是否为Unicode。检查返回true,然后调用
    PyUnicode\u格式
    ,再次调用
    \uuuuuu\uuuu
    。这只是一个猜测,因为我还没有完全阅读这些函数


    str()
    将始终返回str类型,而不是unicode,因此这是有意义的。

    谢谢,虽然我们没有最终的完整答案,但在代码中应该不会太远。我们可能还需要一个理由,因为没有理由,我不知道为什么这种行为是必要的。感谢裁判和代码!