【问题标题】:Install dependencies from setup.py从 setup.py 安装依赖项
【发布时间】:2015-01-10 02:14:41
【问题描述】:

我想知道例如 .deb 包,是否可以在我的 setup.py 中为我的包配置依赖项,然后运行:

$ sudo python setup.py install

它们是自动安装的。已经研究过互联网,但我发现的一切都让我感到困惑,比如“requires”、“install_requires”和“requirements.txt”

【问题讨论】:

标签: python setuptools install-requires


【解决方案1】:

只需在您的 lib 文件夹中创建 requirements.txt 并添加所有依赖项,如下所示:

gunicorn
docutils>=0.3
lxml==0.5a7

然后创建一个setup.py 脚本并读取requirements.txt in:

import os
thelibFolder = os.path.dirname(os.path.realpath(__file__))
requirementPath = thelibFolder + '/requirements.txt'
install_requires = [] # Here we'll get: ["gunicorn", "docutils>=0.3", "lxml==0.5a7"]
if os.path.isfile(requirementPath):
    with open(requirementPath) as f:
        install_requires = f.read().splitlines()
setup(name="yourpackage", install_requires=install_requires, [...])

python setup.py install 的执行将安装您的包和所有依赖项。就像@jwodder 说创建requirements.txt 文件不是强制性的,您可以直接在setup.py 脚本中设置install_requires。但是最好写一个requirements.txt 文件。

在设置功能中,您还必须设置versionpackagesauthor 等,完整示例请阅读文档:https://docs.python.org/3/distutils/setupscript.html

你的包目录如下所示:

├── mypackage
│   ├── mypackage
│   │   ├── __init__.py
│   │   └── mymodule.py
│   ├── requirements.txt
│   └── setup.py

【讨论】:

  • install_requires = list(f.read().splitlines()) 比在循环中一次添加一行要简单得多。 (list 电话可能需要也可能不需要;测试并查看。)
  • 或者像[line for line in f.read().splitlines() if len(line) > 0]这样的东西来防止空行
  • 或者您可以完全放弃requirements.txt 文件,直接在您的setup.py 中写入setup(install_requires=['gunicorn', 'docutils>=0.3', 'lxml==0.5a7'], ...)
  • 我要补充一点,应该忽略 cmets 和空格前缀 install_requires = [line for line in map(str.lstrip, f.read().splitlines()) if len(line) > 0 and not line.startswith('#')]
  • 虽然到目前为止所有提出的解决方案都以某种方式解析requirements.txt 文件并将这些依赖项用作setup.py 中的install_requires,但对于这是否是一种好的做法存在争议:@987654322 @
【解决方案2】:

另一种可能的解决方案

try:
    # for pip >= 10
    from pip._internal.req import parse_requirements
except ImportError:
    # for pip <= 9.0.3
    from pip.req import parse_requirements

def load_requirements(fname):
    reqs = parse_requirements(fname, session="test")
    return [str(ir.req) for ir in reqs]

setup(name="yourpackage", install_requires=load_requirements("requirements.txt"))

【讨论】:

  • 这对我有用。不知道这将来会如何失败(如果它失败了)。
  • @muammar 它可能会失败,因为 pip 明确不应该以编程方式使用。看到pip._internal.req 中的_ 了吗?这意味着它是包内部的一部分,不应在外部使用,并且可能会在没有警告的情况下更改。绝对不能保证它不会突然改变,事实上它已经改变了。
猜你喜欢
  • 1970-01-01
  • 2022-01-15
  • 2014-11-03
  • 2020-09-23
  • 1970-01-01
  • 1970-01-01
  • 2014-11-03
  • 2020-01-09
  • 2013-07-19
相关资源
最近更新 更多