2013-03-17 34 views
5

Rozpakowanie z ciągów działa:`struct.unpack_from` nie działa z` bytearray`?

>>> import struct 
>>> struct.unpack('>h', 'ab') 
(24930,) 
>>> struct.unpack_from('>h', 'zabx', 1) 
(24930,) 

ale jeśli jego bytearray:

>>> struct.unpack_from('>h', bytearray('zabx'), 1) 
Traceback (most recent call last): 
    File "<ipython-input-4-d58338aafb82>", line 1, in <module> 
    struct.unpack_from('>h', bytearray('zabx'), 1) 
TypeError: unpack_from() argument 1 must be string or read-only buffer, not bytearray 

co wydaje się trochę dziwne. Co właściwie mam z tym zrobić? oczywiście mogłem:

>>> struct.unpack_from('>h', str(bytearray('zabx')), 1) 
(24930,) 

ale jestem wyraźnie stara się unikaćkopiowania możliwie dużej ilości pamięci wokół.

+0

Możesz użyć typu bufora, aby odnieść się do łańcucha bez zajmowania większej ilości pamięci, a następnie przekazać go jako argument. –

Odpowiedz

6

Wygląda buffer() jest rozwiązanie:

>>> struct.unpack_from('>h', buffer(bytearray('zabx')), 1) 
(24930,) 

buffer() nie jest kopią oryginalnego, jego widoku:

>>> b0 = bytearray('xaby') 
>>> b1 = buffer(b0) 
>>> b1 
<read-only buffer for ...> 
>>> b1[1:3] 
'ab' 
>>> b0[1:3] = 'nu' 
>>> b1[1:3] 
'nu' 

Alternitively, Ty (? I) można po prostu użyć Pythona 3; ograniczenie jest zniesione:

Python 3.2.3 (default, Jun 8 2012, 05:36:09) 
[GCC 4.7.0 20120507 (Red Hat 4.7.0-5)] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import struct 
>>> struct.unpack_from('>h', b'xaby', 1) 
(24930,) 
>>> struct.unpack_from('>h', bytearray(b'xaby'), 1) 
(24930,) 
>>> 
+0

Dlaczego po prostu nie używać 'buffer ('xaby', index, length)'? To też nie zużywa dodatkowej pamięci. –

+2

Zdarza się, że bit 'struct' owija się wokół' bytearray', wybranym * ponieważ * jest zmienny. Za każdym razem, zamiast utrzymywać widok tylko do odczytu podstawowych, zmiennych danych, wolałbym raczej odtworzyć bity w środku, aby uzyskać dane z ich głównego źródła. Dotyczy to również przechowywania '(24930,)'. Naprawdę chcę rozpakować z 'bytearray'. – SingleNegationElimination

+0

@Asad: Podejrzewam, że tworzenie obiektu 'buffer' zajmuje przynajmniej trochę pamięci. – martineau