簡體   English   中英

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

[英]Printing boolean values True/False with the format() method in Python

我試圖為布爾表達式打印真值表。 在執行此操作時,我偶然發現了以下內容:

>>> 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()True轉換為1 我知道boolint的子類,因此True評估為1

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

但是為什么在第一個示例中使用格式說明符將'True'更改為1

我轉向文檔進行澄清 它唯一說的是:

一般約定是,空格式字符串 ( "" ) 產生的結果與您對該值調用str()結果相同。 非空格式字符串通常會修改結果。

因此,當您使用格式說明符時,字符串會被修改。 但是,如果僅指定了對齊運算符(例如^ ),為什么要從True更改為1呢?

好問題! 我相信我有答案。 這需要在 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_len是否為0 ,如果是,則將obj轉換為字符串。 眾所周知, str(True)'True' ,謎底就結束了!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM