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

前端 未结 1 1907
南笙
南笙 2020-12-30 01:05

I was trying to print a truth table for Boolean expressions. While doing this, I stumbled upon the following:

>>> format(True, \"\") # shows True in         


        
相关标签:
1条回答
  • 2020-12-30 01:44

    Excellent question! I believe I have the answer. This requires digging around through the Python source code in C, so bear with me.

    First, format(obj, format_spec) is just syntactic sugar for obj.__format__(format_spec). For specifically where this occurs, you'd have to look in abstract.c, in the function:

    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);
    
        ...
    }
    

    To find the exact call, we have to look in 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 is actually defined as a macro in formatter_string.c as a function found in 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
    }
    

    And therein lies your answer. A simple check for whether format_spec_len is 0, and if it is, convert obj into a string. As you well know, str(True) is 'True', and the mystery is over!

    0 讨论(0)
提交回复
热议问题