用Python打包有没有更简单的方法?
今天我尝试打包一个django应用。这个应用挺大的,设置文件里我得手动写出所有的包和子包在'package'参数里。然后还得想办法复制一些数据文件、HTML、CSS、图片文件、文档等等。
这样工作真是太糟糕了。我们是计算机科学家,应该让事情自动化,做这些手动的工作简直没道理。
而且如果我改变了应用的结构呢?我还得重新写setup.py。
有没有更好的方法?有没有工具可以自动化这个过程?我真不敢相信像Python这样重视开发者时间的语言,打包竟然这么麻烦。
我希望最终能通过简单的pip install来安装这个应用。我知道有build out,但那也没简单到哪里去,而且对pip不太友好。
4 个回答
0
我觉得你在找的工具是 Buildout。有很多地方可以了解更多关于它的信息,比如 SlideShare 和 Pycon 视频。
你还可以看看其他类似或相关的工具,比如 virtualenv、Fabric 和 PIP。
1
今天我也遇到了这个麻烦。我用了下面这段代码,直接从 Django的setup.py 拿来的。这段代码会在应用的文件系统中查找包和数据文件(前提是你从来不把两者混在一起):
import os
from distutils.command.install import INSTALL_SCHEMES
def fullsplit(path, result=None):
"""
Split a pathname into components (the opposite of os.path.join) in a
platform-neutral way.
"""
if result is None:
result = []
head, tail = os.path.split(path)
if head == '':
return [tail] + result
if head == path:
return result
return fullsplit(head, [tail] + result)
# Tell distutils to put the data_files in platform-specific installation
# locations. See here for an explanation:
# http://groups.google.com/group/comp.lang.python/browse_thread/thread/35ec7b2fed36eaec/2105ee4d9e8042cb
for scheme in INSTALL_SCHEMES.values():
scheme['data'] = scheme['purelib']
# Compile the list of packages available, because distutils doesn't have
# an easy way to do this.
packages, data_files = [], []
root_dir = os.path.dirname(__file__)
if root_dir != '':
os.chdir(root_dir)
myapp_dir = 'myapp'
for dirpath, dirnames, filenames in os.walk(myapp_dir):
# Ignore dirnames that start with '.'
for i, dirname in enumerate(dirnames):
if dirname.startswith('.'): del dirnames[i]
if '__init__.py' in filenames:
packages.append('.'.join(fullsplit(dirpath)))
elif filenames:
data_files.append([dirpath, [os.path.join(dirpath, f) for f in filenames]])
5
至少如果你使用setuptools
(这是一个替代标准库中distutils
的工具),你会得到一个非常棒的功能,叫做find_packages()
。这个功能可以在你项目的根目录运行,返回一个用点号表示的包名列表,这些包名可以用在packages
参数中。
下面是一个例子:
# setup.py
from setuptools import find_packages, setup
setup(
#...
packages=find_packages(exclude='tests'),
#...
)
顺便说一句,打包在每种语言和每个系统中都很糟糕。无论你怎么做,它都不好。