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

Ste*_*ker 22 python string.format boolean string-formatting python-2.7

我试图打印布尔表达式的真值表.在这样做时,我偶然发现了以下情况:

>>> 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'
Run Code Online (Sandbox Code Playgroud)

只要指定格式说明符,就format()转换True1.我知道这bool是一个子类int,因此True评估为1:

>>> format(True, "d") # shows True in a decimal format
'1'
Run Code Online (Sandbox Code Playgroud)

但是,为什么不使用格式说明符的变化'True',以1在第一个例子?

我转向文档澄清.它唯一说的是:

一般惯例是,空格式字符串("")产生的结果与调用str()该值时的结果相同.非空格式字符串通常会修改结果.

因此,当您使用格式说明符时,字符串会被修改.但是,为什么从变化True1,如果对准运营商(例如^)被指定?

huu*_*huu 9

好问题!我相信我有答案.这需要在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);

    ...
}
Run Code Online (Sandbox Code Playgroud)

要找到确切的调用,我们必须查看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
    ...
}
Run Code Online (Sandbox Code Playgroud)

_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
}
Run Code Online (Sandbox Code Playgroud)

这就是你的答案.对于是否一个简单的检查format_spec_len0,如果是,转换obj成字符串.众所周知,str(True)'True',神秘已经结束!

  • 我认为OP问的是为什么``'''.format(True)=='1'``,而不是为什么`'''.'格式(真)=''真'``.或者更确切地说,当后者正确评估时,前者会为前者隐式转换为"int". (4认同)
  • 不是在python中,不是。``&gt;&gt;&gt; type(True)= &lt;type'bool'&gt;``和``type(True)== type(1)== False''。在C解释器中的基础C代码中,由于C缺少bool原语,因此显然将其转换为“ int”,但这无法解释python端的隐式转换。 (2认同)
  • 澄清一下:既然`bool`是`int`的子类,但`bool`没有指定它自己的`__format__`方法,那么来自`int`的方法就是通过常规继承来使用的.在对空格式字符串进行特殊处理的情况下,对于`bool`实现**的对象调用`str()`. (2认同)
  • 那么,为了将非空格式字符串(例如用于对齐)和布尔值打印为 true/false,我们应该首先 str(boolean) 并将其(作为字符串)发送到 format 函数? (2认同)