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()转换True为1.我知道这bool是一个子类int,因此True评估为1:
>>> format(True, "d") # shows True in a decimal format
'1'
Run Code Online (Sandbox Code Playgroud)
但是,为什么不使用格式说明符的变化'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);
...
}
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_len是0,如果是,转换obj成字符串.众所周知,str(True)是'True',神秘已经结束!
| 归档时间: |
|
| 查看次数: |
15422 次 |
| 最近记录: |