在分发应用程序时将所有的鸡蛋合并到一个 zip 文件中会很方便,这样您只需要分发一个 zip 文件和一个可执行文件(一些自定义二进制文件,只需启动, 加载 zip 文件的主要功能并启动 python 或类似功能)。
我在网上看到过一些关于这样做的讨论,但没有关于如何实际做到这一点的示例。
我知道您可以(如果它是 zip 安全的)将鸡蛋转换为 zip 文件。
我不确定的是:
你能以某种方式将所有鸡蛋合并成一个 zip 文件吗?如果有,怎么做?
您将如何从特定的 egg 加载和运行代码?
您如何确保该 egg 中的代码可以访问所有依赖项(即 zip 文件中的其他 Egg)?
人们经常问这类问题并得到诸如此类的答案;使用 py2exe。是的,我明白了,这是一种解决方案。不过,这不是我要在这里问的问题...
最佳答案
您可以使用常规 Python 工具自动完成大部分工作。让我们从干净的 virtualenv 开始。
[zart@feena ~]$ mkdir ziplib-demo
[zart@feena ~]$ cd ziplib-demo
[zart@feena ziplib-demo]$ virtualenv .
New python executable in ./bin/python
Installing setuptools.............done.
Installing pip...............done.
现在让我们安装一组将进入压缩库的软件包。诀窍是强制将它们安装到特定目录中。
(注意:不要在命令行或 pip.conf/pip.ini 中使用 --egg 选项,因为它会破坏文件布局,使其无法在 zip 中导入)
[zart@feena ziplib-demo]$ bin/pip install --install-option --install-lib=$PWD/unpacked waitress
Downloading/unpacking waitress
Downloading waitress-0.8.5.tar.gz (112kB): 112kB downloaded
Running setup.py egg_info for package waitress
Requirement already satisfied (use --upgrade to upgrade): setuptools in ./lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg (from waitress)
Installing collected packages: waitress
Running setup.py install for waitress
Installing waitress-serve script to /home/zart/ziplib-demo/bin
Successfully installed waitress
Cleaning up...
更新:pip 现在有 -t <path>开关,其作用与 --install-option --install-lib= 相同.
现在让我们将它们全部打包到一个 zip 中
[zart@feena ziplib-demo]$ cd unpacked
[zart@feena unpacked]$ ls
waitress waitress-0.8.5-py2.7.egg-info
[zart@feena unpacked]$ zip -r9 ../library.zip *
adding: waitress/ (stored 0%)
adding: waitress/receiver.py (deflated 71%)
adding: waitress/server.pyc (deflated 64%)
adding: waitress/utilities.py (deflated 62%)
adding: waitress/trigger.pyc (deflated 63%)
adding: waitress/trigger.py (deflated 61%)
adding: waitress/receiver.pyc (deflated 60%)
adding: waitress/adjustments.pyc (deflated 51%)
adding: waitress/compat.pyc (deflated 56%)
adding: waitress/adjustments.py (deflated 60%)
adding: waitress/server.py (deflated 68%)
adding: waitress/channel.py (deflated 72%)
adding: waitress/task.pyc (deflated 57%)
adding: waitress/tests/ (stored 0%)
adding: waitress/tests/test_regression.py (deflated 63%)
adding: waitress/tests/test_functional.py (deflated 88%)
adding: waitress/tests/test_parser.pyc (deflated 76%)
adding: waitress/tests/test_trigger.pyc (deflated 73%)
adding: waitress/tests/test_init.py (deflated 72%)
adding: waitress/tests/test_utilities.pyc (deflated 78%)
adding: waitress/tests/test_buffers.pyc (deflated 79%)
adding: waitress/tests/test_trigger.py (deflated 82%)
adding: waitress/tests/test_buffers.py (deflated 86%)
adding: waitress/tests/test_runner.py (deflated 75%)
adding: waitress/tests/test_init.pyc (deflated 69%)
adding: waitress/tests/__init__.pyc (deflated 21%)
adding: waitress/tests/support.pyc (deflated 48%)
adding: waitress/tests/test_utilities.py (deflated 73%)
adding: waitress/tests/test_channel.py (deflated 87%)
adding: waitress/tests/test_task.py (deflated 87%)
adding: waitress/tests/test_functional.pyc (deflated 82%)
adding: waitress/tests/__init__.py (deflated 5%)
adding: waitress/tests/test_compat.pyc (deflated 53%)
adding: waitress/tests/test_receiver.pyc (deflated 79%)
adding: waitress/tests/test_adjustments.py (deflated 78%)
adding: waitress/tests/test_adjustments.pyc (deflated 74%)
adding: waitress/tests/test_server.pyc (deflated 73%)
adding: waitress/tests/fixtureapps/ (stored 0%)
adding: waitress/tests/fixtureapps/filewrapper.pyc (deflated 59%)
adding: waitress/tests/fixtureapps/getline.py (deflated 37%)
adding: waitress/tests/fixtureapps/nocl.py (deflated 47%)
adding: waitress/tests/fixtureapps/sleepy.pyc (deflated 44%)
adding: waitress/tests/fixtureapps/echo.py (deflated 40%)
adding: waitress/tests/fixtureapps/error.py (deflated 52%)
adding: waitress/tests/fixtureapps/nocl.pyc (deflated 48%)
adding: waitress/tests/fixtureapps/getline.pyc (deflated 32%)
adding: waitress/tests/fixtureapps/writecb.pyc (deflated 42%)
adding: waitress/tests/fixtureapps/toolarge.py (deflated 37%)
adding: waitress/tests/fixtureapps/__init__.pyc (deflated 20%)
adding: waitress/tests/fixtureapps/writecb.py (deflated 50%)
adding: waitress/tests/fixtureapps/badcl.pyc (deflated 44%)
adding: waitress/tests/fixtureapps/runner.pyc (deflated 58%)
adding: waitress/tests/fixtureapps/__init__.py (stored 0%)
adding: waitress/tests/fixtureapps/filewrapper.py (deflated 74%)
adding: waitress/tests/fixtureapps/runner.py (deflated 41%)
adding: waitress/tests/fixtureapps/echo.pyc (deflated 42%)
adding: waitress/tests/fixtureapps/groundhog1.jpg (deflated 24%)
adding: waitress/tests/fixtureapps/error.pyc (deflated 48%)
adding: waitress/tests/fixtureapps/sleepy.py (deflated 42%)
adding: waitress/tests/fixtureapps/toolarge.pyc (deflated 43%)
adding: waitress/tests/fixtureapps/badcl.py (deflated 45%)
adding: waitress/tests/support.py (deflated 52%)
adding: waitress/tests/test_task.pyc (deflated 78%)
adding: waitress/tests/test_channel.pyc (deflated 78%)
adding: waitress/tests/test_regression.pyc (deflated 68%)
adding: waitress/tests/test_parser.py (deflated 80%)
adding: waitress/tests/test_server.py (deflated 78%)
adding: waitress/tests/test_receiver.py (deflated 87%)
adding: waitress/tests/test_compat.py (deflated 51%)
adding: waitress/tests/test_runner.pyc (deflated 72%)
adding: waitress/__init__.pyc (deflated 50%)
adding: waitress/channel.pyc (deflated 58%)
adding: waitress/runner.pyc (deflated 54%)
adding: waitress/buffers.py (deflated 74%)
adding: waitress/__init__.py (deflated 61%)
adding: waitress/runner.py (deflated 58%)
adding: waitress/parser.py (deflated 69%)
adding: waitress/compat.py (deflated 69%)
adding: waitress/buffers.pyc (deflated 69%)
adding: waitress/utilities.pyc (deflated 60%)
adding: waitress/parser.pyc (deflated 53%)
adding: waitress/task.py (deflated 72%)
adding: waitress-0.8.5-py2.7.egg-info/ (stored 0%)
adding: waitress-0.8.5-py2.7.egg-info/dependency_links.txt (stored 0%)
adding: waitress-0.8.5-py2.7.egg-info/installed-files.txt (deflated 83%)
adding: waitress-0.8.5-py2.7.egg-info/top_level.txt (stored 0%)
adding: waitress-0.8.5-py2.7.egg-info/PKG-INFO (deflated 65%)
adding: waitress-0.8.5-py2.7.egg-info/not-zip-safe (stored 0%)
adding: waitress-0.8.5-py2.7.egg-info/SOURCES.txt (deflated 71%)
adding: waitress-0.8.5-py2.7.egg-info/entry_points.txt (deflated 33%)
adding: waitress-0.8.5-py2.7.egg-info/requires.txt (deflated 5%)
[zart@feena unpacked]$ cd ..
请注意,这些文件应该在 zip 的顶部,不能只是 zip -r9 library.zip unpacked
检查结果:
[zart@feena ziplib-demo]$ PYTHONPATH=library.zip python
Python 2.7.1 (r271:86832, Apr 12 2011, 16:15:16)
[GCC 4.6.0 20110331 (Red Hat 4.6.0-2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import waitress
>>> waitress
<module 'waitress' from '/home/zart/ziplib-demo/library.zip/waitress/__init__.pyc'>
>>>
>>> from wsgiref.simple_server import demo_app
>>> waitress.serve(demo_app)
serving on http://0.0.0.0:8080
^C>>>
更新:从 python 3.5 开始还有 zipapp module这可以帮助将整个包捆绑到 .pyz 文件中。对于更复杂的需求pyinstaller , py2exe或 py2app可能更符合要求。
关于python - 如何将所有 python 代码捆绑到一个 zip 文件中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17486578/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl