Il codice Python C che gestisce affettare per oggetti che implementano l'sq_slice
fessura, non in grado di gestire eventuali interi sopra Py_ssize_t
(== sys.maxsize
). Lo slot sq_slice
corrisponde all'equivalente C-API del metodo speciale __getslice__
.
Per una sezione a due elementi, Python 2 utilizza uno degli SLICE+*
opcodes; questo viene quindi gestito dallo apply_slice()
function. Questo utilizza _PyEval_SliceIndex
function per convertire gli oggetti indice Python (int
, long
o qualsiasi cosa che implementa lo __index__
method) in un numero intero Py_ssize_t
. Il metodo ha il seguente commento:
/* Extract a slice index from a PyInt or PyLong or an object with the
nb_index slot defined, and store in *pi.
Silently reduce values larger than PY_SSIZE_T_MAX to PY_SSIZE_T_MAX,
and silently boost values less than -PY_SSIZE_T_MAX-1 to -PY_SSIZE_T_MAX-1.
Return 0 on error, 1 on success.
*/
Ciò significa che qualsiasi affettatura in Python 2 utilizzando la sintassi 2-valore è limitato a valori nell'intervallo sys.maxsize
quando viene fornita una fessura sq_slice
.
affettare utilizzando il modulo tre valori (item[start:stop:stride]
) utilizza il BUILD_SLICE
opcode invece (seguita da BINARY_SUBSCR
) e questo crea invece una slice()
object senza limitare a sys.maxsize
.
Se l'oggetto non implementa una fessura sq_slice()
(quindi non __getslice__
presente) la funzione apply_slice()
rientra anche tornare a utilizzare un oggetto slice()
.
Per quanto riguarda questo è un dettaglio di implementazione o parte della lingua: lo Slicings expression documentation distingue tra simple_slicing
e extended_slicing
; il primo consente solo il modulo short_slice
. Per semplice tranciatura gli indici devono essere interi semplici:
Le espressioni di partenza e superiore, se presente, deve esprimere un intero; i valori predefiniti sono zero e lo sys.maxint
, rispettivamente.
Questo suggerisce che Python 2 lingua limita gli indici a sys.maxint
valori, non consentendo interi lunghi. In Python 3 il taglio semplice è stato completamente eliminato dalla lingua.
Se il codice deve sostenere affettare con valori al di là sys.maxsize
e si deve ereditare da un tipo che implementa __getslice__
quindi le opzioni sono:
utilizzare la sintassi di tre valori, con None
per il passo:
Potato()[123:x:None]
per creare slice()
oggetti esplicitamente:
slice()
oggetti in grado di gestire interi long
bene; tuttavia la slice.indices()
method non può gestire lunghezze sopra sys.maxsize
ancora:
>>> import sys
>>> s = slice(0, sys.maxsize + 1)
>>> s
slice(0, 9223372036854775808L, None)
>>> s.stop
9223372036854775808L
>>> s.indices(sys.maxsize + 2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: cannot fit 'long' into an index-sized integer
deve essere detto: "perché sì, vorrei 2^64 fette di questa bella patata". Seriamente però, vorrei davvero avere una risposta – inspectorG4dget
È una fetta .. e succederebbe lo stesso con una porzione più piccola come 'maxint-2: maxint + 2' :) – wim