无法理解 Jupyter notebook 中的输出 ("Learning Cython")

Having trouble to understand the output in a Jupyter notebook ("Learning Cython")

在 O'Reilly 视频教程 "Learning Cython" 第 5 章中,有一个名为 strings.ipynb 的笔记本。

第一个单元加载 Cython 扩展:

%load_ext cython

紧随其后的是这个 Cython 单元格:

%%cython
# cython: language_level=3

def f(char* text):
    print(text)

然后用下面的单元格来证明一个(Unicode)字符串不能用作char*参数:

f('It is I, Arthur, son of Uther Pendragon')

此处的结果是 TypeError 异常。

以上都是我对作者画外音的期待。但是,下一个单元格的结果:

f(b'It is I, Arthur, son of Uther Pendragon')

是这样的:

b'It is I, Arthur, son of Uther Pendragon'

这难倒了我。

在函数 f 中使用了普通的 print,为什么在 Cython 代码中输出看起来好像是 运行 到 repr上面显然是 不是 运行 到 repr?

作者甚至没有在画外音中提到这个(至少对我而言)意想不到的结果。

什么给了?为什么输出看起来像是第一次通过 repr? Python 3 中的字节字符串是否不是 "printable"(即没有 str 方法)并因此退回到 repr

PS:我不得不承认我来自Python2.x并且没有太多接触Python3.x,所以也许区别就在于此。

因为它是。在Python3中,bytes_str使用bytes_repr internally:

static PyObject *
bytes_str(PyObject *op)
{
    if (Py_BytesWarningFlag) {
        if (PyErr_WarnEx(PyExc_BytesWarning,
                         "str() on a bytes instance", 1))
            return NULL;
    }
    return bytes_repr(op);  // call repr on it
}

因此,print 本质上会调用 repr(bytes_instance)