Frage

Ich bin seit fast zwei Jahren ein Python-Programmierer, und ich bin zu schreiben kleine Skripte verwendet, um einige sich wiederholende Aufgaben zu automatisieren ich im Büro zu tun hatte. Nun, anscheinend meine Kollegen bemerkte dies, und sie wollen diese Skripte zu.

Einige von ihnen haben Macs, einige Windows-; Ich habe diese auf Fenster. Ich untersuchte die Möglichkeit, py2exe oder sogar py2app Eingeborenen mein Skript zu machen, aber sie erfüllt mich nie ...

Ich kam zu wissen, dass alle von ihnen JVM auf ihren Systemen haben, so kann ich ihnen eine einzige ausführbare JAR-Datei von meinem Skript so etwas wie Jython verwenden kann?

Wie machbar ist dies ... ich meine, ich hatte keine Ahnung, wie Skripte für Jython zu schreiben, weder scherte ich es, als ich sie schrieb ... welche Art von Problemen wird es geben?

War es hilfreich?

Lösung

Die besten aktuellen Techniken für Ihre Python-Dateien in einem Glas zu verteilen detailliert in diesem Artikel auf Jython Wiki: http://wiki.python.org/jython/JythonFaq/DistributingJythonScripts

Für Ihren Fall, ich glaube, Sie die Datei jython.jar nehmen möchte, die Sie erhalten, wenn Sie Jython installieren und Reißverschluss über die Jython Lib Verzeichnis hinein, dann zip Ihre .py Dateien in und dann eine __run__.py Datei hinzufügen, mit Ihre Startlogik (diese Datei speziell von Jython behandelt wird, und wird die Datei ausgeführt, wenn Sie das Glas mit „java -jar“ nennen).

Dieser Prozess ist auf jeden Fall komplizierter dann in sein sollte, und so haben wir (der Jython-Entwickler) müssen mit einem schönen Werkzeug zu entwickeln, die diese Aufgaben automatisieren, aber jetzt das sind die besten Methoden. Im Folgenden wird ich das Rezept am unteren Rande des obigen Artikels bin Kopieren (leicht modifizierte, die Problembeschreibung passen) Ihnen die Lösung ein Gefühl zu geben.

Erstellen Sie das Grundglas:

$ cd $JYTHON_HOME
$ cp jython.jar jythonlib.jar
$ zip -r jythonlib.jar Lib

Fügen Sie weitere Module in das Gefäß:

$ cd $MY_APP_DIRECTORY
$ cp $JYTHON_HOME/jythonlib.jar myapp.jar
$ zip myapp.jar Lib/showobjs.py
# Add path to additional jar file.
$ jar ufm myapp.jar othermanifest.mf

Fügen Sie den __run__.py Modul:

# Copy or rename your start-up script, removing the "__name__  == '__main__'" check.
$ cp mymainscript.py __run__.py
# Add your start-up script (__run__.py) to the jar.
$ zip myapp.jar __run__.py
# Add path to main jar to the CLASSPATH environment variable.
$ export CLASSPATH=/path/to/my/app/myapp.jar:$CLASSPATH

Auf MS Windows, die letzte Zeile, die Umgebungsvariable CLASSPATH einstellen, würde wie folgt aussehen:

set CLASSPATH=C:\path\to\my\app\myapp.jar;%CLASSPATH%

Oder wieder auf MS Windows, verwenden Sie die Systemsteuerung und die Systemeigenschaften die Umgebungsvariable CLASSPATH zu setzen.

Führen Sie die Anwendung:

$ java -jar myapp.jar mymainscript.py arg1 arg2

Oder, wenn Sie Ihr Start-up-Skript in das Gefäß gegeben haben, verwenden Sie eine der folgenden Möglichkeiten:

$ java org.python.util.jython -jar myapp.jar arg1 arg2
$ java -cp myapp.jar org.python.util.jython -jar myapp.jar arg1 arg2
$ java -jar myapp.jar -jar myapp.jar arg1 arg2

Die doppelte -jar ist ein bisschen ärgerlich, wenn Sie so wollen, das vermeiden und nutzen Sie die angenehmere:

$ java -jar myapp.jar arg1

Sie werden ein bisschen mehr Arbeit zu tun, bis wir so etwas wie dieses in eine Zukunft Jython erhalten [Update: JarRunner Teil von Jython 2.5.1 ist]. Hier finden Sie einige Java-Code, der automatisch für die __run__.py aussieht, und es läuft. Beachten Sie, dass dies in dieser Klasse mein erster Versuch ist. Lassen Sie mich wissen, ob es verbessert werden muss!

package org.python.util;

import org.python.core.imp;
import org.python.core.PySystemState;

public class JarRunner {

    public static void run(String[] args) {
        final String runner = "__run__";
        String[] argv = new String[args.length + 1];
        argv[0] = runner;
        System.arraycopy(args, 0, argv, 1, args.length);
        PySystemState.initialize(PySystemState.getBaseProperties(), null, argv);
        imp.load(runner);
    }

    public static void main(String[] args) {
        run(args);
    }
}

habe ich diesen Code in das org.python.util Paket, denn das ist, wo es gehen würde, wenn wir es in einem zukünftigen Jython entscheiden aufzunehmen. Um zu kompilieren, müssen Sie jython.jar (oder Ihr myapp.jar) in den Classpath setzen wie:

$ javac -classpath myapp.jar org/python/util/JarRunner.java

Dann müssen Sie JarRunner.class zu Ihrem Glas hinzuzufügen (die Klassendatei müssen in org / Python / util / JarRunner.class sein) Aufruf Glas auf dem „org“ Verzeichnis wird den ganzen Weg bekommen in Ihre Glas.

$ jar uf org

Fügen Sie diese in einer Datei, die Sie das Manifest aktualisieren verwenden wird, ein guter Name ist manifest.txt:

Main-Class: org.python.util.JarRunner

Dann das Glas Manifest aktualisieren:

$ jar ufm myapp.jar manifest.txt

Nun sollten Sie in der Lage sein, Ihre App wie folgt auszuführen:

$ java -jar myapp.jar

Andere Tipps

Ich erlebte ein ähnliches Problem, dass ich einfache Befehlszeile erstellen können, wollen Anrufe für meine jython Apps, nicht verlangen, dass der Benutzer den jython Installationsprozess durchlaufen, und in der Lage, die jython Scripts anhängen Bibliotheksabhängigkeiten zu haben, bei Laufzeit sys.path, um Kern Java-Code enthalten.

# append Java library elements to path
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", "lib", "poi-3.8-20120326.jar"))

Wenn die ‚jython‘ Launcher ausgeführt werden explizit auf der Kommandozeile, auf Unix-Systemen, es läuft gerade einen großen Shell-Skript richtig einen Java-Kommandozeilenaufruf zu bilden. Dieser jython Launcher scheint bei Erreichen zurück zu einem Kern-Installation von jython eine Abhängigkeit zu haben, und von irgendeiner Weise der Magie ermöglicht die richtige Handhabung von .jar-Dateien in die sys.path zur Laufzeit aus meiner Py Skripte hinzugefügt werden. Sie können sehen, was der Anruf und Blockausführung durch die folgende:

jython --print run_form.py
java -Xmx512m -Xss1024k -Dfile.encoding=UTF-8 -classpath /Applications/jython2.5.2/jython.jar: -Dpython.home=/Applications/jython2.5.2 -Dpython.executable=/Applications/jython2.5.2/bin/jython org.python.util.jython run_form.py

Aber es ist immer noch nur ein JVM Anheizen und eine Klassendatei ausgeführt wird. So war mein Ziel, um diesen Java-Aufruf zu einem eigenständigen jython.jar in meiner Distribution lib zu machen, so dass Benutzer würden keine zusätzlichen Installationsschritte tun müssen, um starten meine Py scripted Dienstprogramme verwenden.

java -Xmx512m -Xss1024k -classpath ../../lib/jython.jar org.python.util.jython run_form.py

Das Problem ist, dass das Verhalten unterschiedlich ist genug, dass ich Antworten wie diese bekommen würde:

  File "run_form.py", line 14, in <module>
    import xls_mgr
  File "/Users/test/Eclipse/workspace/test_code/py/test/xls_mgr.py", line 17, in <module>
    import org.apache.poi.hssf.extractor as xls_extractor
ImportError: No module named apache

Nun könnte man sagen, dass ich nur die JAR-Dateien in das -classpath hinzufügen, die in der Tat habe ich versucht, aber ich würde das gleiche Ergebnis.

Der Vorschlag, alle Ihre .class-Dateien in einem jython.jar Bündelung klang nicht ansprechend, überhaupt zu mir. Es wäre ein Chaos sein und würde die Java / Python Hybrid-Anwendung zu fest an die jython Verteilung binden. Also diese Idee würde nicht fliegen. Schließlich, nach viel suchen, lief ich über Bug # 1776 an jython.org, die für ein Jahr als kritisch notiert ist und eine Hälfte, aber ich sehe nicht, dass das neueste Updates zu jython ein Update integrieren. wenn Sie Probleme nach wie vor, mit mit jython umfassen Ihre separaten JAR-Dateien, sollten Sie dies lesen.

http://bugs.jython.org/issue1776

Dort werden Sie die vorübergehende Lösung für dieses. In meinem Fall habe ich das Glas Apache POI-Datei und unjar'ed es in seine eigene separate lib und dann modifiziert, um den sys.path Eintrag Punkt in das Verzeichnis anstelle des Glases:

sys.path.append('/Users/test/Eclipse/workspace/test_code/lib/poi_lib')

Nun, wenn ich jython weist Java, meine lokalen jython.jar Referenzierung, läuft das Dienstprogramm nur Peachy. Jetzt kann ich einfache Skripte oder Batch-Dateien erstellen, um eine nahtlose Befehlszeile Erfahrung für meinen Py Dienstprogramme zu machen, die der Benutzer ohne zusätzliche Installationsschritte ausgeführt werden kann.

Der Befehl ‚jythonc‘ sollte in der Lage sein, Ihre .py Quelle in JVM-Bytecode kompiliert, was es tragbar machen sollte zu einem Java installieren. Oder so las ich an: http: //hell.org.ua/Docs/oreilly/other2/python/0596001886_pythonian-chp-25-sect-3.html

Für Ihre Python-Skripten in einer Art und Weise zu verteilen, die nicht über eine native Python-Installation erfordert, können Sie auch versuchen, Nuitka , die Ihren Python grundsätzlich ++ Code in C-Code übersetzt, der dann zu einem echten nativen binären kompiliert wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top