python migration jython cpython

Migrando de CPython a Jython



migration (6)

Hasta ahora, he notado dos problemas adicionales:

  • La cadena de ''a'' es ''a'' no está garantizada (y es solo una implementación casual en CPython). Esto podría ser un problema grave, y realmente estaba en una de las bibliotecas que estaba portando (Jinja2). Las pruebas unitarias son (como siempre) tus mejores amigos!

Jython 2.5b0 (trunk:5540, Oct 31 2008, 13:55:41) >>> ''a'' is ''a'' True >>> s = ''a'' >>> ''a'' is s False >>> ''a'' == s True >>> intern(''a'') is intern(s) True

Aquí está la misma sesión en CPython:

Python 2.5.2 (r252:60911, Oct 5 2008, 19:24:49) >>> ''a'' is ''a'' True >>> s = ''a'' >>> ''a'' is s True >>> ''a'' == s True >>> intern(''a'') is intern(s) True

  • Las funciones de os.spawn * no están implementadas. En su lugar, use subprocess.call. Me sorprendió realmente, ya que la implementación que utiliza subprocess.call sería fácil, y estoy seguro de que aceptarán parches.

(He estado haciendo algo similar a ti, portando una aplicación recientemente)

Estoy considerando mover mi código (alrededor de 30K LOC) de CPython a Jython, para poder tener una mejor integración con mi código java.

¿Hay una lista de verificación o una guía que debería consultar para ayudarme con la migración? ¿Alguien tiene experiencia haciendo algo similar?

Después de leer el sitio de Jython , la mayoría de los problemas parecen demasiado oscuros para molestarme.

Me di cuenta de que:

  • la seguridad de la rosca es un problema
  • El soporte de Unicode parece ser bastante diferente, lo cual puede ser un problema para mí
  • mysqldb no funciona y debe ser reemplazado con zxJDBC

¿Algo más?

Pregunta relacionada: ¿Cuáles son algunas estrategias para escribir código python que funciona en CPython, Jython y IronPython?


Cuando cambié un proyecto de CPython a Jython hace algún tiempo, realicé una reducción de velocidad de hasta 50x para las secciones de tiempo crítico. Por eso me quedé con CPython.

Sin embargo, eso podría haber cambiado ahora con las versiones actuales.


En primer lugar, debo decir que la implementación de Jython es muy buena. La mayoría de las cosas "solo funcionan".

Aquí hay algunas cosas que he encontrado:

  • C módulos no están disponibles, por supuesto.

  • open (''archivo''). read () no cierra automáticamente el archivo. Esto tiene que ver con la diferencia en el recolector de basura. Esto puede causar problemas con demasiados archivos abiertos. Es mejor utilizar el modismo "with open (''file'') as fp".

  • Establecer el directorio de trabajo actual (usando os.setcwd ()) funciona para el código de Python, pero no para el código de Java. Emula el directorio de trabajo actual para todo lo relacionado con archivos, pero solo puede hacerlo para Jython.

  • El análisis XML intentará validar una DTD externa si está disponible. Esto puede causar desaceleraciones masivas en el código de manejo XML porque el analizador descargará la DTD a través de la red. Informé de este problema , pero hasta ahora permanece sin corregir.

  • El método __ del __ se invoca muy tarde en el código Jython, no inmediatamente después de que se elimine la última referencia al objeto.

Hay una lista antigua de diferencias , pero una lista reciente no está disponible.


También es posible que desee investigar JPype . No estoy seguro de cuán maduro es en comparación con Jython, pero debería permitir que CPython acceda al código de Java.


Recientemente, trabajé en un proyecto para un profesor en mi escuela con un grupo. Al principio, se decidió que escribiríamos el proyecto en Python. Definitivamente deberíamos haber usado CPython. Escribimos el programa en Python y finalmente todas nuestras pruebas unitarias funcionaron. Debido a que la mayoría de la gente ya tiene Java instalado en sus computadoras, y no en Python, decidimos simplemente implementarlo como un contenedor Jython. Por lo tanto, escribimos la GUI con Swing porque está incluida en la biblioteca estándar de Java.

La primera vez que ejecuté el programa con Jython, se bloqueó de inmediato. Por un lado, ".fieldnames" de csv.reader siempre parecía ser None. Por lo tanto, tuve que cambiar varias partes de nuestro código para evitar esto.

También se bloqueó una sección diferente de mi código, que funcionó bien con CPython. Jython me acusó de hacer referencia a una variable antes de asignarle algo (lo que me volvía loco y realmente no era el caso). Este es un ejemplo: clasificación externa de ActiveState''s Recipe

Peor aún, el rendimiento fue horrible. Básicamente, este código combina varios archivos CSV, uno de los cuales era de aproximadamente 2 GB. En CPython, se ejecutó en 8.5 minutos. En Jython, funcionó en 25 minutos.

Estos problemas ocurrieron con 2.5.2rc2 (la última al momento de escribir esta publicación).


Estoy comenzando esto como una wiki recopilada de las otras respuestas y mi experiencia. Siéntete libre de editar y agregar cosas, pero por favor trata de apegarte a consejos prácticos en lugar de una lista de cosas rotas. Aquí hay una lista antigua de diferencias del sitio de Jython.

Administracion de recursos

Jython no utiliza el recuento de referencias, por lo que se liberan recursos ya que son basura recolectada, que es mucho más tarde de lo que verías en el programa CPython equivalente.

  • open(''file'').read() no cierra automáticamente el archivo. Mejor utilizar el with open(''file'') as fp idioma.
  • El método __ del __ se invoca muy tarde en el código Jython, no inmediatamente después de que se elimine la última referencia al objeto.

Integración de MySQL

mysqldb es un módulo de CA, y por lo tanto no funcionará en jython. En su lugar, debe usar com.ziclix.python.sql.zxJDBC , que viene incluido con Jython.

Reemplace el siguiente código MySQLdb:

connection = MySQLdb.connect(host, user, passwd, db, use_unicode=True, chatset=''utf8'')

Con:

url = "jdbc:mysql://%s/%s?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull" % (host, db) connections = zxJDBC.connect(url, user, passwd, "com.mysql.jdbc.Driver")

También deberá reemplazar todas las _mysql_exception con zxJDBC .

Finalmente, deberá reemplazar los marcadores de posición de consulta de %s a ? .

Unicode

  • No puede expresar caracteres Unicode ilegales en Jython. Intentar algo como unichr(0xd800) causaría una excepción, y tener un literal u''/ud800'' en tu código solo causará estragos.

Cosas perdidas

  • C módulos no están disponibles, por supuesto.
  • Las funciones de os.spawn * no están implementadas. En su lugar, use subprocess.call.

Actuación

  • Para la mayoría de las cargas de trabajo, Jython será mucho más lento que CPython. Los informes son algo entre 3 y 50 veces más lentos.

Comunidad

El proyecto Jython sigue vivo, pero no se mueve rápidamente. La lista de distribución de dev tiene aproximadamente 20 mensajes por mes, y parece que solo hay unos 2 desarrolladores que están confirmando el código últimamente.