Python 3.x 我应该如何生成requirements.txt?皮普冻结不是一个好办法

Python 3.x 我应该如何生成requirements.txt?皮普冻结不是一个好办法,python-3.x,pip,Python 3.x,Pip,如何为Python项目生成requirements.txt 这是我与皮普冻结的问题。假设我的包P需要A、B、C。假设C是一个导入X、Y、Z的库,但P只需要X。如果我: 1) Install A 2) Install B 3) Install C, which installs X, Y, Z 4) Do a pip freeze into P's requirements.txt 那么p的requirements.txt将如下所示: 1) A 2) B 3) C 4) X 5) Y 6) Z

如何为Python项目生成requirements.txt

这是我与皮普冻结的问题。假设我的包P需要A、B、C。假设C是一个导入X、Y、Z的库,但P只需要X。如果我:

1) Install A
2) Install B
3) Install C, which installs X, Y, Z
4) Do a pip freeze into P's requirements.txt 
那么p的requirements.txt将如下所示:

1) A
2) B
3) C
4) X
5) Y
6) Z
但是在我的Python安装中,Y和Z并不是运行p所必需的


据我所知,运行
pipfreeze
生成p的需求将显示依赖项的所有依赖项,因此是p的实际依赖项的超集

virtualenv的目的是完全控制安装的软件包

假设您只列出了A、B、C和X。每次从该需求文件创建新的virtualenv时,您都会得到Y和Z的最新版本。这有几个问题:

  • 你不可能知道你没有使用Y:对于一个足够复杂的项目,几乎不可能审核每个代码路径以确保C永远不会调用Y。你不再只担心自己的代码;你也在担心C的代码。这根本无法扩展
  • 即使只是导入Y,也在使用它。:Python允许在导入时执行任意代码。新版本的Y在导入时可能会做各种令人讨厌的事情,比如打印到stdout,猴子补丁X,或者任何你能想象到的事情。一个设计良好的Y不应该做这些事情,但是你会发现PyPI上的包的质量变化很大
  • 新版本的Y可以引入新的依赖项:如果您包含新版本的Y,您可能最终也会将包W添加到您的virtualenv中,因为新版本的Y需要它。随着越来越多的软件包的加入,前两个问题会进一步恶化。更糟糕的是,您可能会发现新版本的Y依赖于新版本的X,在这种情况下,您将无法得到您真正想要的软件包
  • 生成一个已知的良好配置更为重要
    pip冻结
    的设计目的不是为了找出最低要求。它的设计目的是使一个完整的应用程序能够一致地部署到许多不同的环境中。这意味着它会在谨慎方面出错,并列出所有可能合理影响您的项目的内容

  • 出于这些原因,您不应该尝试从需求文件中删除Y和Z。它根据项目中的导入生成requirements.txt

  • 安装
    pipreqs
    库(例如
    conda安装-c conda forge pipreqs
  • 将目录更改为项目文件夹(
    cd/your repository
  • 运行命令
    pipreqs--force
  • 或者干脆
    pipreqs——强制您的/repository

    请参阅官方来源中的其他信息:

    我在另一篇stackoverflow帖子中回答了这个问题,我建议使用
    pip compile
    from

    我不认为这是个问题。如果需求指定了依赖项的依赖项,那么它会造成任何伤害吗?即使您手动从requirements.txt文件中删除X、Y、Z,在安装C时也会安装X、Y、Z。pip冻结使安装依赖项对用户透明。在运行pip freeze之前,请注意在虚拟环境中安装与您的项目相关的所有内容。我猜“问题”的意思是我希望P的最低要求集作为P的requirements.txt运行。但是由于上面的问题,需求膨胀到一个比P运行所需的要大得多的集合。你需要Y和Z来运行C。通过传递性,P需要Y和Z来运行。requirements.txt的要点是,只有当您自己更改包时,包才会更改。如果我们没有记录Y和Z的版本,那是不可能的。那是错误的。C是一个具有很多功能的库。其中的某些部分依赖于Y和Z。但是,P调用的部分不是,因此P仍然可以导入C,如果只安装了X,则运行。请记住,许多Python错误只在运行时遇到,因此如果P只调用C导入X的部分,那么一切都很好。我对我的问题进行了编辑,使之更加清晰。Python是一种高度动态的语言。假设出现了一个新版本的Y,它在导入时将X到处修补。你不想在你的虚拟电视里看到这个,对吧?好吧,如果你不在requirements.txt中锁定Y版本,你可能会得到它。好的,谢谢你,这是非常有用的,也是一个很好的学习答案!