在Python中使用format()方法打印布尔值True / False

发布于 2021-01-29 15:23:53

我试图为布尔表达式打印真值表。在执行此操作时,我偶然发现了以下内容:

>>> format(True, "") # shows True in a string representation, same as str(True)
'True'
>>> format(True, "^") # centers True in the middle of the output string
'1'

我指定格式说明符后,立即format()将其转换True1。我知道这bool是的子类int,因此True计算结果为1

>>> format(True, "d") # shows True in a decimal format
'1'

但是,为什么在第一个示例中使用格式说明符会'True'变为1

我转向文档进行澄清。它唯一说的是:

通常的约定是,空的格式字符串("")会产生与调用str()该值相同的结果。非空格式字符串通常会修改结果。

因此,当您使用格式说明符时,字符串将被修改。但是True1如果 指定对齐运算符(例如^),为什么要从更改为?

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

    很好的问题!我相信我有答案。这需要深入研究C语言中的Python源代码,所以请多多包涵。

    首先,format(obj, format_spec)只是的语法糖obj.__format__(format_spec)。对于发生这种情况的特定位置,您必须在函数中查看abstract.c

    PyObject *
    PyObject_Format(PyObject* obj, PyObject *format_spec)
    {
        PyObject *empty = NULL;
        PyObject *result = NULL;
    
        ...
    
        if (PyInstance_Check(obj)) {
            /* We're an instance of a classic class */
    HERE -> PyObject *bound_method = PyObject_GetAttrString(obj, "__format__");
            if (bound_method != NULL) {
                result = PyObject_CallFunctionObjArgs(bound_method,
                                                      format_spec,
                                                      NULL);
    
        ...
    }
    

    为了找到确切的调用,我们必须查看intobject.c

    static PyObject *
    int__format__(PyObject *self, PyObject *args)
    {
        PyObject *format_spec;
    
        ...
    
        return _PyInt_FormatAdvanced(self,
                         ^           PyBytes_AS_STRING(format_spec),
                         |           PyBytes_GET_SIZE(format_spec));
                   LET'S FIND THIS
        ...
    }
    

    _PyInt_FormatAdvanced实际上定义为在宏formatter_string.c作为函数中发现formatter.h

    static PyObject*
    format_int_or_long(PyObject* obj,
                   STRINGLIB_CHAR *format_spec,
               Py_ssize_t format_spec_len,
               IntOrLongToString tostring)
    {
        PyObject *result = NULL;
        PyObject *tmp = NULL;
        InternalFormatSpec format;
    
        /* check for the special case of zero length format spec, make
           it equivalent to str(obj) */
        if (format_spec_len == 0) {
            result = STRINGLIB_TOSTR(obj);   <- EXPLICIT CAST ALERT!
            goto done;
        }
    
        ... // Otherwise, format the object as if it were an integer
    }
    

    答案就在这里。简单检查是否format_spec_len0,如果是,则将其转换obj为字符串。如您所知,str(True)'True',谜团结束了!



知识点
面圈网VIP题库

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

去下载看看