我正在尝试编写一个处理字节字符串的 Python C 扩展,我有一些基本上适用于 Python 2.x 和 Python 3.x 的东西。
对于 Python 2.x 代码,在我的函数开始附近,我目前有一行:
if (!PyArg_ParseTuple(args, "s#:in_bytes", &src_ptr, &src_len))
...
我注意到 s#
格式说明符接受 Unicode 字符串和字节字符串。我真的只是希望它接受字节串并拒绝 Unicode。对于 Python 2.x,这可能已经“足够好了”——标准的 hashlib
似乎做同样的事情,接受 Unicode 和字节串。然而,Python 3.x 旨在清理 Unicode/byte 字符串困惑,而不是让两者可以互换。
所以,我很惊讶地发现 in Python 3.x, the s
format specifiers PyArg_ParseTuple()
似乎仍然接受 Unicode 并提供 Unicode 的“默认编码字符串版本”。这似乎违背了 Python 3.x 的原则,使得 s
格式说明符在实践中无法使用。我的分析是否正确,还是我遗漏了什么?
查看 Python 3.x 的 hashlib
实现(例如,参见 md5module.c
、函数 MD5_update()
及其对 GET_BUFFER_VIEW_OR_ERROUT()
宏的使用)我明白了它避免了 s
格式说明符,只接受一个通用对象(O
说明符),然后使用 GET_BUFFER_VIEW_OR_ERROUT()
进行各种显式类型检查。宏。这是我们必须做的吗?
最佳答案
我同意你的看法——这是 Python 3 的 C API 迁移显然没有设计得像 Python 编码器可见部分那样仔细和彻底的几个地方之一。我也同意,目前最好的解决方法可能是关注“缓冲区 View ”,根据该宏——直到并且除非更好的东西被设计到 future 的 Python C API 中(不要屏住呼吸等待它发生,虽然;-).
关于python - PyArg_ParseTuple() "s"格式说明符在 Python 3.x C API 中有用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2422572/