我一直是一个Python程序员将近两年了,我习惯了写小脚本来自动完成一些重复的任务我在办公室做。 现在,显然我的同事们注意到了这一点,他们希望这些脚本了。
他们中的一些有Mac电脑,某些Windows; 我在Windows上做这些。 我调查使用py2exe甚至py2app使我的剧本的当地人的可能性,但他们从来没有满足我...
我才知道,他们都有JVM在他们的系统,这样我就可以给他们使用类似的Jython可能是我的脚本一个单一的可执行的JAR文件?
如何可行的是这个......我的意思是,我不知道如何编写Jython脚本,也没有我关心它,当我写了他们... ...它给什么样的问题?
在一个罐子里散发你的Python文件目前最好的技术有详细的这篇文章对Jython的维基在: http://wiki.python.org/jython/JythonFaq/DistributingJythonScripts
对于你的情况,我想你会想带当您安装的Jython,你得到拉链和Jython的lib目录进去,然后压缩在你的.py文件的jython.jar文件,然后添加一个__run__.py
与您的文件启动逻辑(此文件由Jython的特殊处理,将是,当你调用与“Java的罐子”的jar执行的文件)。
这个过程肯定是比较复杂那么应该是,等我们(Jython的开发者)需要拿出一个很好的工具,将自动完成这些任务,但现在这些都是最好的方法。 下面,我在复制上述文章底部的配方(略作修改,以适应您的问题描述)给你的解决方案的意义。
创建基本的jar:
$ cd $JYTHON_HOME
$ cp jython.jar jythonlib.jar
$ zip -r jythonlib.jar Lib
添加其他模块的jar:
$ 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
添加__run__.py
模块:
# 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
在MS Windows,最后一行,设置CLASSPATH环境变量,会是这个样子:
set CLASSPATH=C:\path\to\my\app\myapp.jar;%CLASSPATH%
或者,再在MS Windows,使用控制面板和系统属性设置CLASSPATH环境变量。
运行应用程序:
$ java -jar myapp.jar mymainscript.py arg1 arg2
或者,如果你已经添加你的启动脚本的罐子,使用下列之一:
$ 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
双罐子是一种恼人的,所以如果你想避免这一点,得到了更加赏心悦目:
$ java -jar myapp.jar arg1
你必须做更多的工作,直到我们得到这样的事情成为未来的Jython [更新:JarRunner是Jython的2.5.1的一部分。 下面是查找的一些Java代码__run__.py
自动,并运行它。 请注意,这是我第一次尝试这个类。 让我知道,如果它需要改进!
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);
}
}
我把这个代码放到org.python.util包,因为这就是如果我们决定将其包括在未来的Jython它会去。 要编译它,你需要把jython.jar(或您的myapp.jar)到像类路径:
$ javac -classpath myapp.jar org/python/util/JarRunner.java
然后,你需要JarRunner.class添加到您的罐子(类文件将需要在组织/蟒蛇/ UTIL / JarRunner.class)呼吁“组织”目录罐子会得到整个路径到您的罐子。
$ jar uf org
这种添加到您将使用更新的清单文件,一个好名字是manifest.txt:
Main-Class: org.python.util.JarRunner
然后更新JAR的清单:
$ jar ufm myapp.jar manifest.txt
现在,你应该能够运行你的应用程序是这样的:
$ java -jar myapp.jar
我经历了一个类似的问题,我希望能够创建简单的命令行呼吁我的Jython的应用程序,而不需要用户经过Jython安装过程,并能有Jython脚本在运行时SYS附加库的依赖。路径以便包括核心的Java代码。
# 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"))
当命令行中运行“Jython的发射明确,在Unix系统中,它只是有一个大的shell脚本适当地形成一个java命令行调用。 这Jython的启动似乎对可追溯到核心安装的Jython的依赖,并通过魔法某种方式允许被添加到在运行时的sys.path的.jar文件的正确处理从我的.py脚本中。 您可以通过下面看看呼叫和块执行:
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
但它仍然只是发射了一个JVM和运行类文件。 所以我的目标是能够使这个java调用到独立存在于我的发布程序lib目录下的jython.jar这样用户就不需要做任何额外的安装步骤,开始使用我的.py脚本工具。
java -Xmx512m -Xss1024k -classpath ../../lib/jython.jar org.python.util.jython run_form.py
麻烦的是,该行为是不够的不同,我会得到这样的答复:
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
现在你可能会说,我的jar文件只是添加到-classpath,这其实我试过,但我会得到相同的结果。
捆绑所有的.class文件的一个jython.jar的建议并没有动听,我在所有。 这将是一个烂摊子,并会在Java / Python的混合应用程序太紧密结合为Jython分布。 这样想法是不会飞。 最后,大量的搜索后,我遇到了bug#1776跑在jython.org,它已被列为了一年半的关键,但我不认为这对Jython的最新的更新包括修复。 不过,如果你正在与具有Jython的包括你的独立的jar文件的问题,您应该阅读。
http://bugs.jython.org/issue1776
在那里,你会发现这个临时的解决方法。 就我而言,我拿着的Apache POI jar文件,unjar'ed它变成了自己独立的lib目录下,然后修改sys.path的条目指向的目录,而不是JAR:
sys.path.append('/Users/test/Eclipse/workspace/test_code/lib/poi_lib')
现在,当我在Java的方式,引用我的本地jython.jar运行Jython中,该实用程序运行只是桃色。 现在,我可以创建简单的脚本或批处理文件,使我的.py公用事业,用户可以无需任何额外的安装步骤运行无缝的命令行经验。
该“jythonc也”命令应该能够编译您的.py源成JVM字节码,这样就应该移植到任何Java安装。 还是让我阅读: http://hell.org.ua/Docs/oreilly/other2/python/0596001886_pythonian-chp-25-sect-3.html
对于不需要本地Python安装的方式分发您的Python脚本,你也可以尝试Nuitka ,这基本上会将您的Python代码C ++代码,然后将其编译成一个真正的原生二进制文件。