Domanda

Sto pensando di spostare il mio codice (circa 30K LOC) da CPython a Jython, in modo da poter avere una migliore integrazione con il mio codice Java.

Esiste una lista di controllo o una guida che dovrei consultare per aiutarmi nella migrazione? Qualcuno ha esperienza nel fare qualcosa di simile?

Dalla lettura del sito Jython , la maggior parte dei problemi sembra troppo oscura per disturbare me.

L'ho notato:

  • la sicurezza del thread è un problema
  • Il supporto Unicode sembra essere abbastanza diverso, il che potrebbe essere un problema per me
  • mysqldb non funziona e deve essere sostituito con zxJDBC

Qualcos'altro?

Domanda correlata: Quali sono alcune strategie per scrivere codice Python che funziona in CPython, Jython e IronPython

È stato utile?

Soluzione 3

Sto iniziando come un wiki raccolto dalle altre risposte e dalla mia esperienza. Sentiti libero di modificare e aggiungere elementi, ma prova a seguire i consigli pratici piuttosto che un elenco di cose rotte. Ecco un vecchio elenco di differenze dal sito Jython.

Gestione delle risorse

Jython non usa il conteggio dei riferimenti, quindi le risorse vengono rilasciate così come sono sono i rifiuti raccolti, che è molto più tardi che vedresti nell'equivalente Programma CPython

  • open ('file'). read () non chiude automaticamente il file. Meglio usare con open ('file') come idioma fp .
  • Il metodo __ del __ viene invocato molto tardi nel codice Jython, non immediatamente dopo che l'ultimo riferimento all'oggetto è stato eliminato.

Integrazione MySQL

mysqldb è un modulo c, quindi non funzionerà in jython. Invece tu dovrebbe utilizzare com.ziclix.python.sql.zxJDBC , fornito in bundle con Jython.

Sostituisci il seguente codice 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")

Dovrai anche sostituire tutti i _mysql_exception con zxJDBC .

Infine, dovrai sostituire i segnaposto della query da % s a ? .

Unicode

  • Non puoi esprimere caratteri Unicode illegali in Jython. Provare qualcosa come unichr (0xd800) provocherebbe un'eccezione e avere un u '\ ud800' letterale nel tuo codice causerà solo il caos.

Cose mancanti

  • I moduli C non sono disponibili, ovviamente.
  • Le funzioni
  • os.spawn * non sono implementate. Utilizzare invece subprocess.call.

Prestazioni

  • Per la maggior parte dei carichi di lavoro, Jython sarà molto più lento di CPython. I rapporti sono qualcosa tra 3 e 50 volte più lento.

Comunità

Il progetto Jython è ancora vivo, ma non è in rapido movimento. Il mailing list di sviluppo ha circa 20 messaggi al mese e sembrano esserci solo circa 2 sviluppatori codice impegnativo ultimamente.

Altri suggerimenti

Prima di tutto, devo dire che l'implementazione di Jython è molto buona. La maggior parte delle cose "funziona e basta".

Ecco alcune cose che ho riscontrato:

  • I moduli C non sono disponibili, ovviamente.

  • open ('file'). read () non chiude automaticamente il file. Questo ha a che fare con la differenza nel Garbage Collector. Ciò può causare problemi con troppi file aperti. È meglio usare " con open ('file') come fp " idioma.

  • L'impostazione della directory di lavoro corrente (usando os.setcwd ()) funziona per il codice Python, ma non per il codice Java. Emula la directory di lavoro corrente per tutto ciò che riguarda i file, ma può farlo solo per Jython.

  • L'analisi XML proverà a convalidare un DTD esterno se è disponibile. Ciò può causare enormi rallentamenti nel codice di gestione XML perché il parser scaricherà il DTD sulla rete. Ho segnalato questo problema , ma finora non è stato risolto.

  • Il metodo __ del __ viene invocato molto tardi nel codice Jython, non immediatamente dopo l'eliminazione dell'ultimo riferimento all'oggetto.

Esiste un vecchio elenco di differenze , ma un elenco recente non è disponibile.

Finora ho notato altri due problemi:

  • Il string interning 'a' is 'a' non è garantito (ed è solo un colpo di fortuna di implementazione su CPython). Questo potrebbe essere un problema serio, ed era davvero in una delle biblioteche che stavo portando (Jinja2). I test unitari sono (come sempre) i tuoi migliori amici!
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

Ecco la stessa sessione su 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

    Le funzioni
  • os.spawn * non sono implementate. Utilizzare invece subprocess.call. Sono rimasto davvero sorpreso, poiché l'implementazione che utilizza subprocess.call sarebbe semplice e sono sicuro che accetteranno le patch.

(Ho fatto una cosa simile a te, porting un'app di recente)

Quando ho passato un progetto da CPython a Jython qualche tempo fa, ho realizzato una riduzione fino a 50 volte per le sezioni temporali. Per questo motivo sono rimasto con CPython.

Tuttavia, ciò potrebbe essere cambiato ora con le versioni correnti.

Potresti anche voler ricercare JPype . Non sono sicuro di quanto sia maturo rispetto a Jython, ma dovrebbe consentire a CPython di accedere al codice Java.

Di recente, ho lavorato a un progetto per un professore della mia scuola con un gruppo. All'inizio fu deciso di scrivere il progetto in Python. Avremmo sicuramente dovuto usare CPython. Abbiamo scritto il programma in Python e tutti i nostri test unitari alla fine hanno funzionato. Poiché la maggior parte delle persone ha già installato Java sui propri computer, e non Python, abbiamo deciso di implementarlo come un vaso Jython. Pertanto abbiamo scritto la GUI con Swing, perché inclusa nella libreria standard di Java.

La prima volta che ho eseguito il programma con Jython, si è bloccato immediatamente. Per uno, csv.reader's " .fieldnames " sembrava sempre essere Nessuno. Pertanto ho dovuto modificare diverse parti del nostro codice per ovviare a questo.

Anche un'altra sezione del mio codice si è bloccata, il che ha funzionato bene con CPython. Jython mi ha accusato di aver fatto riferimento a una variabile prima che gli fosse assegnato qualcosa (il che mi ha fatto impazzire e in realtà non era il caso). Questo è un esempio: Ordinamento esterno della ricetta del codice di ActiveState

Peggio ancora, la performance è stata orribile. Fondamentalmente questo codice ha combinato diversi file CSV, uno dei quali era di circa 2 GB. In CPython, ha funzionato in 8,5 minuti. In Jython, ha funzionato in 25 minuti.

Questi problemi si sono verificati con 2.5.2rc2 (l'ultimo al momento della stesura di questo post).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top