traducir inglés ingles español cómo como python generator pickle python-stackless

python - ingles - cómo se dice en inglés



¿Por qué los generadores no pueden ser encurtidos? (2)

La salmuera de Python (estoy hablando de Python 2.5 / 2.6 / 2.7 estándar aquí) no puede encerrar bloqueos, objetos de archivo, etc.

Tampoco puede generar generadores de salmuera y expresiones lambda (o cualquier otro código anónimo), porque la salmuera realmente solo almacena referencias de nombres.

En el caso de bloqueos y funciones dependientes del sistema operativo, la razón por la que no puede decantarlos es obvia y tiene sentido.

Pero, ¿por qué no puedes molestar a los generadores?

Nota : solo para mayor claridad: estoy interesado en la razón fundamental (o las suposiciones y las elecciones que se tomaron en esa decisión de diseño), no en "porque le da un error Pickle".

Me doy cuenta de que la pregunta es un tanto generalizada, por lo que aquí hay una regla de oro para saber si la respondió: "Si se plantearan estas suposiciones o si el tipo de generador permitido de alguna manera estuviera más restringido, ¿volverían a funcionar los generadores de decapado?"


Hay mucha información sobre esto disponible. Para conocer la "palabra oficial" sobre el problema, lea el problema de Python bugtracker (cerrado) .

El razonamiento principal, por una de las personas que tomó la decisión, se detalla en este blog :

Dado que un generador es esencialmente una función mejorada, deberíamos guardar su código de bytes, que no garantiza la compatibilidad con versiones anteriores de las versiones de Python, y su marco, que contiene el estado del generador, como variables locales, cierres y el puntero de instrucciones. Y esto último es bastante engorroso de lograr, ya que básicamente requiere que todo el intérprete sea elegible. Por lo tanto, cualquier soporte para los generadores de decapado requeriría una gran cantidad de cambios en el núcleo de CPython.

Ahora bien, si un objeto no admitido por pickle (por ejemplo, un identificador de archivo, un socket, una conexión de base de datos, etc.) aparece en las variables locales de un generador, entonces ese generador no podría ser decapado automáticamente, independientemente de cualquier soporte de pickle para los generadores que podamos implementar. Entonces, en ese caso, aún tendría que proporcionar __getstate__ personalizados __getstate__ y __setstate__ . Este problema hace que cualquier soporte de decapado para generadores sea bastante limitado.

Y se mencionan dos soluciones sugeridas:

De todos modos, si necesita una característica de este tipo, mire Python sin pila que hace todo lo anterior. Y como el intérprete de Stackless es seleccionable, también obtiene la migración del proceso de forma gratuita. Esto significa que puede interrumpir un tasklet (el nombre de los hilos verdes de Stackless), encurtirlo, enviar el pickle a otra máquina, desmarcarlo, reanudar el tasklet, y voilà que acaba de migrar un proceso. ¡Esta es una característica genial!

Pero en mi humilde opinión, la mejor solución a este problema es volver a escribir los generadores como simples iteradores (es decir, uno con un método __next__ ). Los iteradores son fáciles y eficientes en cuanto al espacio para decapar porque su estado es explícito. Sin embargo, aún tendría que manejar objetos que representen algún estado externo explícitamente; No puedes evitar esto.


Realmente puedes, dependiendo de la implementación. PyPy y Stackless Python permiten esto (hasta cierto punto de todos modos):

Python 2.7.1 (dcae7aed462b, Aug 17 2011, 09:46:15) [PyPy 1.6.0 with GCC 4.0.1] on darwin Type "help", "copyright", "credits" or "license" for more information. And now for something completely different: ``Not your usual analyses.'''' >>>> import pickle >>>> gen = (x for x in range(100)) >>>> next(gen) 0 >>>> pickled = pickle.dumps(gen) >>>> next(pickle.loads(pickled)) 1

En CPython también es posible crear un objeto iterador para simular un generador seleccionable.