Pasando la syntax de la porción de Python a las funciones

En Python, ¿es posible encapsular exactamente la syntax de división común y pasarla? Sé que puedo usar slice o __slice__ para emular a slicing. Pero quiero pasar exactamente la misma syntax que pondría entre los corchetes que se utilizarían con __getitem__ .

Por ejemplo, supongamos que escribí una función para devolver parte de una lista.

 def get_important_values(some_list, some_condition, slice): elems = filter(some_condition, some_list) return elems[slice] 

Esto funciona bien si paso manualmente en un objeto de división:

 In [233]: get_important_values([1,2,3,4], lambda x: (x%2) == 0, slice(0, None)) Out[233]: [2, 4] 

Pero lo que quiero que el usuario pase es exactamente el mismo corte que habrían usado con __getitem__ :

 get_important_values([1,2,3,4], lambda x: (x%2) == 0, (0:-1) ) # or get_important_values([1,2,3,4], lambda x: (x%2) == 0, (0:) ) 

Obviamente esto genera un error de syntax. Pero, ¿hay alguna forma de hacer que esto funcione, sin escribir mi propio mini analizador para los cortes de tipo x:y:t , y obligar al usuario a pasarlos como cadenas?

Motivación

Podría hacer que esta función de ejemplo devuelva algo directamente segmentable, como el filter(some_condition, some_list) , que será el resultado completo como una lista. Sin embargo, en mi ejemplo real, la función interna es mucho más complicada, y si conozco la porción que el usuario desea con anticipación, puedo simplificar enormemente el cálculo. Pero quiero que el usuario no tenga que hacer mucho más para decirme la porción antes de tiempo.

Tal vez algo a lo largo de las siguientes líneas te funcione:

 class SliceMaker(object): def __getitem__(self, item): return item make_slice = SliceMaker() print make_slice[3] print make_slice[0:] print make_slice[:-1] print make_slice[1:10:2,...] 

La idea es que use make_slice[] lugar de crear manualmente instancias de slice . Al hacer esto, podrá utilizar la syntax de corchetes familiar en todo su esplendor.

En resumen, no. Esa syntax solo es válida en el contexto del operador [] . Podría sugerirle que acepte una tupla como entrada y luego pase esa tupla a slice() . Alternativamente, tal vez podría rediseñar lo que esté haciendo para que get_important_values() se implemente de alguna manera como un objeto que se puede cortar.

Por ejemplo, podrías hacer algo como:

 class ImportantValueGetter(object): def __init__(self, some_list, some_condition): self.some_list = some_list self.some_condition = some_condition def __getitem__(self, key): # Here key could be an int or a slice; you can do some type checking if necessary return filter(self.some_condition, self.some_list)[key] 

Probablemente puedas hacer uno mejor convirtiendo esto en un Contenedor ABC de algún tipo, pero esa es la idea general.

Una forma (para cortes simples) sería que el argumento de corte sea un dict o un int,

es decir

 get_important_values([1, 2, 3, 4], lambda x: (x%2) == 0, {0: -1}) 

o

 get_important_values([1, 2, 3, 4], lambda x: (x%2) == 0, 1) 

entonces la syntax se mantendría más o menos igual.

Sin embargo, esto no funcionaría, porque cuando quieres hacer cosas como

 some_list[0:6:10..]