10

Python 2.7为缓冲区和内存视图对象引入了一个新的 API 。

我阅读了关于它们的文档,我想我了解了基本概念(以原始形式访问对象的内部数据而不复制它,我认为这意味着获取对象数据的“更快且更少内存占用”的方式),但要真正理解文档,读者应该对 C 有一定的了解,这超出了我的掌握范围。

如果有人愿意花时间做以下事情,我将不胜感激:

  • 用“外行术语”解释缓冲区和 memoryview 对象,以及
  • 描述一个场景,其中使用缓冲区和 memoryview 对象将是做事的“Pythonic 方式”
4

2 回答 2

5

这是我写的哈希函数中的一行:

M = tuple(buffer(M, i, Nb) for i in range(0, len(M), Nb))

这会将长字符串 M 拆分为长度为 Nb 的较短“字符串”,其中 Nb 是我一次可以处理的字节数/字符数。它在不复制字符串的任何部分的情况下执行此操作,如果我像这样对字符串进行切片,就会发生这种情况:

M = tuple(M[i*Nb:i*Nb+Nb] for i in range(0, len(M), Nb))

我现在可以迭代 M 就像我切片它一样:

H = key
for Mi in M:
    H = encrypt(H, Mi)

基本上,缓冲区和内存视图是处理 Python 中字符串的不变性以及切片等一般复制行为的有效方法。内存视图就像一个缓冲区,除了你也可以写入它,而不仅仅是读取。

虽然主缓冲区/内存视图文档是关于 C 实现的,但标准类型页面在内存视图下有一些信息: http ://docs.python.org/library/stdtypes.html#memoryview-type

编辑:在我的书签中找到这个,http ://webcache.googleusercontent.com/search?q=cache:Ago7BXl1_qUJ:mattgattis.com/2010/3/9/python-memory-views+site:mattgattis.com+python&hl= en&client=firefox-a&gl=us&strip=1是一个非常好的简短文章。

编辑 2:原来我从何时应该使用内存视图?首先,该问题从未得到详细回答,并且链接已失效,因此希望这会有所帮助。

于 2011-07-18T17:47:41.907 回答
1

我一直在寻找的部分答案buffer是“旧方式”,即memoryview新方式,但被向后移植到 2.7 - 请参阅此处的存档博客

这并没有回答我的问题,即为什么我认为我在 2.7 中实现的 C API 允许我构造 abuffer而不是memoryview...

memoryview在 Python 2.7 中工作,您需要Py_TPFLAGS_HAVE_NEWBUFFERtp_flags. 我发现内置bytearray源代码是一个很好的参考;它在Include/bytearrayobject.h和中Objects/bytearrayobject.c

于 2013-11-13T16:06:24.783 回答