Pregunta

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?

Al leer el sitio Jython , la mayoría de los problemas parecen demasiado oscuros para molestarlos yo

Me di cuenta de que:

  • la seguridad del hilo es un problema
  • El soporte Unicode parece ser bastante diferente, lo que puede ser un problema para mí
  • mysqldb no funciona y necesita ser reemplazado con zxJDBC

¿Algo más?

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

¿Fue útil?

Solución 3

Estoy comenzando esto como un wiki recopilado de las otras respuestas y mi experiencia. Siéntase libre de editar y agregar cosas, pero trate de seguir consejos prácticos en lugar de una lista de cosas rotas. Aquí hay una antigua lista de diferencias del sitio Jython.

Gestión de recursos

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

  • open ('file'). read () no cierra automáticamente el archivo. Mejor use el con open ('file') como idioma de fp .
  • 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 MySQL

mysqldb es un módulo c, y por lo tanto no funcionará en jython. En cambio, tu debería 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 la consulta de % s a ? .

Unicode

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

Cosas perdidas

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

Rendimiento

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

Comunidad

El proyecto Jython todavía está vivo, pero no se mueve rápidamente. los lista de correo del desarrollador tiene alrededor de 20 mensajes al mes, y parece que solo hay alrededor de 2 desarrolladores confirmando código últimamente.

Otros consejos

En primer lugar, tengo que 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:

  • Los módulos C 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 usar " con open ('file') como fp " modismo.

  • Establecer el directorio de trabajo actual (usando os.setcwd ()) funciona para el código Python, pero no para el código 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 ralentizaciones masivas en el código de manejo XML porque el analizador descargará el DTD a través de la red. informé este problema , pero hasta ahora permanece sin reparar.

  • 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.

Hasta ahora, he notado dos problemas más:

  • La cadena de internamiento 'a' es 'a' no está garantizada (y es solo una casualidad de implementación 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
  • os.spawn * no están implementadas. En su lugar, use subprocess.call. Realmente me sorprendió, ya que la implementación usando 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)

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

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

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 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 todas nuestras pruebas unitarias finalmente funcionaron. Debido a que la mayoría de las personas ya tienen Java instalado en sus computadoras, y no Python, decidimos implementarlo simplemente como un Jython jar. 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, csv.reader's " .fieldnames " siempre parecía ser ninguno. Por lo tanto, tuve que cambiar varias partes de nuestro código para solucionar 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 que se le asignara algo (lo que me volvió loco y realmente no era el caso). Este es un ejemplo: Clasificación externa de la receta de código de ActiveState

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, se ejecutó en 25 minutos.

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top