用Python打包有没有更简单的方法?

4 投票
4 回答
636 浏览
提问于 2025-04-16 05:10

今天我尝试打包一个django应用。这个应用挺大的,设置文件里我得手动写出所有的包和子包在'package'参数里。然后还得想办法复制一些数据文件、HTML、CSS、图片文件、文档等等。

这样工作真是太糟糕了。我们是计算机科学家,应该让事情自动化,做这些手动的工作简直没道理。

而且如果我改变了应用的结构呢?我还得重新写setup.py。

有没有更好的方法?有没有工具可以自动化这个过程?我真不敢相信像Python这样重视开发者时间的语言,打包竟然这么麻烦。

我希望最终能通过简单的pip install来安装这个应用。我知道有build out,但那也没简单到哪里去,而且对pip不太友好。

4 个回答

0

我觉得你在找的工具是 Buildout。有很多地方可以了解更多关于它的信息,比如 SlideSharePycon 视频

你还可以看看其他类似或相关的工具,比如 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'),
    #...
)

顺便说一句,打包在每种语言和每个系统中都很糟糕。无论你怎么做,它都不好。

撰写回答