gpt4 book ai didi

Python:如何获得指向字节数组的可变切片?

转载 作者:太空宇宙 更新时间:2023-11-04 05:36:36 25 4
gpt4 key购买 nike

我想要一个 buffer 的版本指向 bytearray并且是可变的。我想将它传递给像 io.BufferedIOBase.readinto() 这样的 I/O 函数没有循环中的内存分配开销。

import sys, struct

ba = bytearray(2000)
lenbuf = bytearray(8)

with open(sys.argv[1]) as fp:
while True:
fp.readinto(lenbuf) # efficient version of fp.read(8)
dat_len = struct.unpack("Q", lenbuf)
buf = buffer(ba, 0, dat_len)
fp.readinto(buf) # efficient version of fp.read(dat_len), but
# yields TypeError: must be read-write buffer, not buffer
my_parse(buf)

我也试过 buf = memoryview (buffer(ba, 0, length)) 但得到(本质上)相同的错误。

我认为使用 Python 不应该等同于不关注运行时性能。

我默认使用安装在 Cent6 上的 Python 2.6,但如果确实需要,可以切换到 2.7 或 3.x。

谢谢!

更新 <- 不,这不是要走的路

我对切片到 bytearray 的行为感到困惑。下面的记录表明我可以简单地从 bytearray 中取出一个切片:

>>> x = bytearray(10**8)
>>> cProfile.run('x[10:13]="abc"')
2 function calls in 0.000 seconds

Ordered by: standard name

ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}

>>> x.count(b'\x00')
3999999997
>>> len(x)
4000000000

>>> cProfile.run('x[10:13]="abcd"') # intentionally try an inefficient case
2 function calls in 0.750 seconds

Ordered by: standard name

ncalls tottime percall cumtime percall filename:lineno(function)
1 0.750 0.750 0.750 0.750 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}

>>> len(x)
4000000001

但是,“可变切片”在分配单个字节时无法按预期工作:

>>> x = bytearray(4*10**9)
>>> x = bytearray(10)
>>> x[2] = 0xff
>>> x.count(b'\x00')
9
>>> x[3:5][0] = 0xff
>>> x.count(b'\x00')
9 # WHAT

我不会在我的应用程序中真正使用单字节赋值,但我担心是否存在任何根本性的误解。

最佳答案

您可以让它读取多余的数据,然后在从文件读取更多数据之前简单地使用字节数组中的所有多余数据。

否则你可以使用 numpy:

import sys, struct
import numpy as np

buf = np.zeros(2000, dtype=np.uint8)
lenbuf = bytearray(8)

with open(sys.argv[1]) as fp:
while True:
fp.readinto(lenbuf)
dat_len = struct.unpack("Q", lenbuf)
fp.readinto(buf[:dat_len])
my_parse(buf[:dat_len])

numpy 创建您需要的读写缓冲区,索引 [:dat_len] 返回数据子集的“ View ”而不是副本。由于 numpy 数组符合缓冲区协议(protocol),您可以进一步将它们与 struct.unpack() 一起使用,就好像它们是字节数组/缓冲区一样。

关于Python:如何获得指向字节数组的可变切片?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35403929/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com