【问题标题】:How to locally develop a python package?如何在本地开发一个python包?
【发布时间】:2019-02-14 08:09:43
【问题描述】:

我正在尝试对现有的 python 模块进行更改,然后在本地对其进行测试。最好的方法是什么?

我克隆了 github 模块并进行了更改,但我不确定如何导入本地包而不是已经安装的包。

【问题讨论】:

  • 您是否在询问如何在试验/测试您的副本时导入您的副本,或者如何将其作为“供应商代码”嵌入到您自己的应用程序中,以便它使用嵌入的副本而不是安装的任何内容,或者如何通过公开发布的版本将它安装到您的 virtualenv/user/system 站点包中,或者......?
  • 如果您从本地模块源的位置运行python 命令,它将在全局版本之前首先加载。您还可以创建虚拟环境。
  • 或者你可以打开一个新的分支,修改它,然后当你想使用它时签出这个分支。

标签: python python-import


【解决方案1】:

TL;博士

你可以:

  • 覆盖一个模块/包,方法是在您将运行的脚本的相同文件夹中创建另一个具有同名的模块/包。
  • 使用 develop mode

我推荐阅读this article,它很好地解释了模块和包。


覆盖模块/包

说明

您需要使用与您想要的模块/包相同的名称创建一个模块或包(它没有区别),并将其放在与将要使用它的脚本相同的文件夹中。

这是因为从 sys.path 变量开始搜索模块(其中第一个元素是脚本的目录)

示例

  1. 创建包含以下内容的脚本:
import platform

print(platform.system())
  1. 启动它 (python your_test_script.py) 应该返回

  2. 现在在上一个测试脚本的相同目录创建一个名为exactly的文件platform.py以下内容:

def system():
    """Just a docstring passing by"""
    return "We have just overwritten default 'platform' module...\nFeel the force!"
  1. 如果您现在启动脚本,您会注意到输出不同:


开发模式

说明

如果您的项目更复杂,更好的选择。

从包的根目录(您将在其中启动构建):

pip install -e ./ 

现在您可以编辑代码并实时查看更改..


来自The Joy of Packaging

它将一个链接(实际上是 *.pth 文件)放入到您的代码的 python 安装中,以便安装您的包,但任何更改都会立即生效。

这样你所有的测试代码和客户端代码等都可以像往常一样导入你的包。

没有 sys.path 黑客攻击

【讨论】:

    【解决方案2】:

    进行此类测试的最简单方法是创建一个虚拟环境,然后将包安装到development mode

    假设您使用的是 Linux,它看起来像这样。

    $ virtualenv dev_env
    $ source dev_env/bin/activate
    $ cd ~/project_folder
    $ pip install -e .
    

    此工作流程不会覆盖您系统上已安装的软件包。另一个可能更简单的替代方案是只使用一个 IDE 为您处理大部分内容,例如PyCharm.

    【讨论】:

    • 我如何在 pycharm 上做到这一点?
    • 您可以将两个项目导入同一个工作区。从技术上讲,我什至不认为你需要一个 virtualenv,但只创建一个进行隔离可能会很好。
    【解决方案3】:

    answer by abc 将模块路径添加到系统路径的方法适用于本地即时测试,但它不是完整的解决方案,例如当需要编译 C 代码或必须设置命令行挂钩时。对于完整的测试,您可能需要安装该软件包。

    一个典型的 Python 有一个setup.py,可以打包成一个分发文件(wheel,...),然后可以从本地文件安装到本地。

    工作流程是:

    • 创建可分发的包(可能包含类似python setup.py bdist_wheel 的命令)
    • 创建一个新的虚拟环境进行测试(或卸载任何以前安装的、未修改的软件包版本)
    • 从本地创建的分发包安装包(可能像pip install --no-index --find-links=..一样简单)
    • 运行测试

    这导致每个未来的软件包用户都会遇到完全相同的情况,并且是一个完整的测试(包括安装过程),但这也是一个很大的努力,这就是为什么我通常只使用系统路径方法在开发过程中,但完整的安装方式仅在发布之前。

    【讨论】:

      【解决方案4】:

      一种方法是使用sys.path()
      例如:

      import sys
      sys.path.insert(0, path/to/module)
      

      这样,您在查找模块时会优先考虑特定路径。
      这意味着您要导入的模块将首先在 path/to/module 中搜索,然后在 sys.path 中的其他目录中搜索。

      这种方法的优点是这个新顺序将只保留在您的脚本中,而不会更改其他顺序的导入顺序。

      注意:出于开发目的,您应该使用 @eandersson 建议的 virtualenv。

      【讨论】:

      • 路径只是文件系统上的路径吗? “~/project/module”我不断收到错误 ModuleNotFound
      • 这取决于它的结构。通常,您会有一个文件夹,其中包含 __init__.py 文件。与其他脚本/文件夹。
      【解决方案5】:

      您可能应该在virtual environment 中完成大部分开发工作。您的工作流程可能如下所示:

      # activate the virtual environment in ~/vpy
      . $HOME/vpy/bin/activate
      
      # install my app and its dependencies
      cd $HOME/src/myapp
      pip install -e .
      
      # use my forked library instead
      cd $HOME/src/forkedlib
      pip install -e .
      pytest # or whatever tests the forked lib has
      
      # try it out with my application too
      cd $HOME/src/myapp
      pytest # or whatever tests your app has
      myapp
      

      pip install -e 有一些魔力,因此,每当您 import 库中的模块时,它都会直接路由到签出的源代码树,因此如果您在 forkedlib 中进行编辑然后重新运行 @ 987654326@,你会直接看到这些变化。

      完成后,您可以pip uninstall forkedlib 然后重新运行pip install -e . 以重新安装应用程序的(声明的)依赖项。 (或者删除并重新创建虚拟环境,如果这样更容易的话。)

      【讨论】:

        猜你喜欢
        • 2015-08-19
        • 1970-01-01
        • 2023-03-21
        • 1970-01-01
        • 1970-01-01
        • 2012-08-25
        • 1970-01-01
        • 2021-10-03
        • 1970-01-01
        相关资源
        最近更新 更多