【python\import】import时,优先调用本地项目代码(用setup.py等方法构造的库),而非pip安装的库 || 代码测试

本文讲述了如何在Python中导入本地文件夹作为库,而非通过pip安装的官方版本。涉及到pyproject.toml和setup.py文件的配置,以及在开发过程中遇到的常见问题,如`setuptools-scm`版本检测错误和`libaec.h`缺失等问题的解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【start:20231103】

引言

问题描述

疑问:假设我正在执行A.py文件,如果我有一个文件夹是cellseg_models_pytorch,位置是在该执行文件的父文件夹下,但是我之前用pip install cellseg_models_pytorch命令安装过官方版本的cellseg_models_pytorch,
现在我在A.py文件中import cellseg_models_pytorch时,我希望导入的是我的cellseg_models_pytorch文件夹,而不是pip之前install的,该怎么做?

问题总结:

  • 如何import自己的文件夹做为库,而不是pip install的?
  • import自己的文件夹作为库后,如何指定库的位置为源代码,而不是另起炉灶?

具体案例

曾经pip install cellseg_models_pytorch过,

但现在,我想在pannuke_nuclei_segmentation_cppnet.ipynb文件中,

在使用from cellseg_models_pytorch.datamodules import PannukeDataModule语句时,

不用pip下载的库,而是用以cellseg_models_pytorch为文件夹名的本地项目代码,作为被import的cellseg_models_pytorch库:

在这里插入图片描述

这应该如何实现?


【ref】关于python优先调用项目目录下的代码而不是安装的包

构造自己的python库

构造库所涉及的文件

在Python开发过程中,我们经常需要使用第三方库和模块来扩展我们的功能。当我们使用pip命令安装这些库时,有时会遇到目录不可安装的错误。这个错误表示Python无法识别当前目录作为一个可安装的包或模块。

这个错误通常是由于缺少一个setup.py或pyproject.toml文件所导致的。这些文件是Python包的构建配置文件,用于告诉Python如何构建和安装这个包。

【ref】Python ERROR: 目录不可安装。既没有’setup.py’,也没有’pyproject.toml’

pyproject.toml文件和setup.py文件这两个文件在Python项目中都扮演着重要的角色,pyproject.toml用于项目的元数据和构建配置,而setup.py则用于项目的安装和打包配置。理解这些文件的作用可以帮助您更好地管理和配置您的Python项目。

pyproject.toml

pyproject.toml文件通常用于定义Python项目的元数据、构建系统配置和依赖项。它是一种新的配置文件格式,用于替代旧的setup.cfg文件。在pyproject.toml中,您可以指定项目的元数据信息,如名称、版本、作者等,同时还可以指定项目的构建工具和配置,如build-system部分用于指定项目所使用的构建工具,比如flitsetuptools等。此外,您还可以在pyproject.toml中指定项目的依赖项,包括需要的Python版本以及其他依赖库。

setup.py

setup.py文件通常用于定义Python项目的安装和打包信息。在这个文件中,您可以使用setuptools库来定义项目的安装要求、版本等信息。通常会定义项目的名称、版本、作者、描述以及其他配置。您还可以指定项目的依赖项和其他安装时的配置选项。

构造库所涉及的命令

如果有pyproject.toml文件,或者有setup.py文件,则可以在cmd中,进入对应的父文件夹路径(删掉原来的.eggs等文件),然后通过以下命令来安装本地库:

  • pip install -e . 是源安装,适用于开发环境,允许即时查看对代码的修改,无需重新安装。
  • python setup.py develop 是开发模式的安装方式,源代码的修改会即时反映在已安装的包中,适用于在开发期间持续编辑和测试。
  • python setup.py install 是传统的二进制安装方式,适用于正式环境,编辑后的源代码修改不会立即生效,需要重新运行安装命令。

pip install -e .

这是一个源安装(editable install)的命令,用于在开发模式下安装 Python 包。主要特点包括:

  • 符号链接或拷贝源代码: 通过创建符号链接或拷贝源代码,将包的源代码链接到安装路径。这意味着你可以在原始代码的基础上进行编辑,而不需要重新安装。

  • 用于开发环境: 通常在开发过程中使用,允许即时查看对代码的修改。对于共享代码和即时反馈很有用。

  • 使用pip工具: 使用了 pip 工具,这是一个通用的包管理工具,可以处理依赖关系和其他相关的事务。

使用示例(可以使用 --editable-e 选项):

pip install -e .

比如,用该方法生成cellpose库后,该库就是原始代码,__init__.py 的位置如下:

/home/linxq/code/cell_seg_workflow/src_cite/segment/cellpose-main/cellpose/__init__.py

python setup.py develop

pip install -e . 相似,也是一种源安装方式,通过创建符号链接或拷贝源代码,将包的源代码链接到安装路径。

  • 目的: 用于在开发模式下安装包,允许你在源代码的基础上进行编辑,而不需要重新安装。

  • 效果: 创建符号链接(或拷贝)将包的源代码链接到安装路径,使得你可以在原始代码的基础上进行修改,而不需要重新安装。

  • 编辑后效果: 如果你在安装后对源代码进行了修改,这些修改将会立即反映在已安装的包中,无需重新运行安装命令。

使用示例:

python setup.py develop

区别:

  • pip install -e . 使用了 pip 工具,它是一个通用的包管理工具,可以处理依赖关系和其他相关的事务。
  • python setup.py develop 使用了 setuptools 提供的安装脚本,这是一个用于构建、发布和安装 Python 包的工具。

python setup.py install

这是一个传统的二进制安装的命令,用于将 Python 包的二进制文件安装到系统中。主要特点包括:

  • 复制二进制文件: 将包的二进制文件(通常是编译后的 .pyc 文件)复制到指定的安装目录中。

  • 用于正式安装: 通常在准备将包分发给其他人或在生产环境中使用时使用。

  • 使用setuptools工具: 使用了 setuptools 提供的安装脚本,这是一个用于构建、发布和安装 Python 包的工具。

使用示例:

python setup.py install

比如,用该方法生成cellpose库后,该库保存在了conda envs的“site-packages”里,__init__.py 的位置如下::

/home/linxq/.conda/envs/seg38/lib/python3.8/site-packages/cellpose-3.0.0-py3.8.egg/cellpose/__init__.py

其他问题

构造库与importlib联动的问题

使用:

import importlib
importlib.reload(xxx)

时,如果xxx是经过上文中提到的“构造”操作的本地项目,reload方法好像会失效

实战:本地Cellpose库的安装

执行:

(seg38) linxq:~/code/cell_seg_workflow/src_cite/segment/cellpose-main$ python setup.py install

后,我们期待得到的效果是:

在这里插入图片描述

但是实际上会遇到下列各种异常情况:

情况1:LookupError: setuptools-scm was unable to detect version

运行:

(cpp310) linxq:~/code/cell_seg_workflow/src_cite/segment/cellpose-main$ python setup.py install

返回:

linxq:~/code/cell_seg_workflow/src_cite/segment/cellpose-main$ python setup.py install
/opt/anaconda3/lib/python3.11/site-packages/setuptools/__init__.py:84: _DeprecatedInstaller: setuptools.installer and fetch_build_eggs are deprecated.
!!

        ********************************************************************************
        Requirements should be satisfied by a PEP 517 installer.
        If you are using pip, you can try `pip install --use-pep517`.
        ********************************************************************************

!!
  dist.fetch_build_eggs(dist.setup_requires)
Warning: 'classifiers' should be a list, got type 'tuple'
WARNING setuptools_scm.pyproject_reading toml section missing 'pyproject.toml does not contain a tool.setuptools_scm section'
Traceback (most recent call last):
  File "/home/linxq/code/cell_seg_workflow/src_cite/segment/cellpose-main/setup.py", line 73, in <module>
    setup(
  File "/opt/anaconda3/lib/python3.11/site-packages/setuptools/__init__.py", line 107, in setup
    return distutils.core.setup(**attrs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/anaconda3/lib/python3.11/site-packages/setuptools/_distutils/core.py", line 147, in setup
    _setup_distribution = dist = klass(attrs)
                                 ^^^^^^^^^^^^
  File "/opt/anaconda3/lib/python3.11/site-packages/setuptools/dist.py", line 486, in __init__
    _Distribution.__init__(
  File "/opt/anaconda3/lib/python3.11/site-packages/setuptools/_distutils/dist.py", line 283, in __init__
    self.finalize_options()
  File "/opt/anaconda3/lib/python3.11/site-packages/setuptools/dist.py", line 925, in finalize_options
    ep(self)
  File "/opt/anaconda3/lib/python3.11/site-packages/setuptools/dist.py", line 945, in _finalize_setup_keywords
    ep.load()(self, ep.name, value)
  File "/home/linxq/code/cell_seg_workflow/src_cite/segment/cellpose-main/.eggs/setuptools_scm-8.0.4-py3.11.egg/setuptools_scm/_integration/setuptools.py", line 101, in version_keyword
    _assign_version(dist, config)
  File "/home/linxq/code/cell_seg_workflow/src_cite/segment/cellpose-main/.eggs/setuptools_scm-8.0.4-py3.11.egg/setuptools_scm/_integration/setuptools.py", line 56, in _assign_version
    _version_missing(config)
  File "/home/linxq/code/cell_seg_workflow/src_cite/segment/cellpose-main/.eggs/setuptools_scm-8.0.4-py3.11.egg/setuptools_scm/_get_version_impl.py", line 112, in _version_missing
    raise LookupError(
LookupError: setuptools-scm was unable to detect version for /home/linxq/code/cell_seg_workflow/src_cite/segment/cellpose-main.

Make sure you're either building from a fully intact git repository or PyPI tarballs. Most other sources (such as GitHub's tarballs, a git checkout without the .git folder) don't contain the necessary metadata and will not work.

For example, if you're using pip, instead of https://github.com/user/proj/archive/master.zip use git+https://github.com/user/proj.git#egg=proj

解决方法

首先,要确定python版本正确(python==3.8):把环境cpp310换成seg38;

其次,要指定好自己的库的版本,比如,在setup.py文件的setup变量中:

在,

setup(
    name="cellpose",
    license="BSD",
    ...
)

中,插入version(版本数字可以自己编):

setup(
    name="cellpose",
    version="3.0.0",
    license="BSD",
    ...
)

具体如下:

在这里插入图片描述

然后再依次执行:

conda create -n seg38 python==3.8
conda activate seg38

pip install "/home/linxq/.conda/whl/torch-1.13.1+cu117-cp38-cp38-linux_x86_64.whl"
pip install -r environment2.yml
python setup.py install

情况2:fatal error: libaec.h: No such file or directory

/home/linxq/.conda/envs/seg38/lib/python3.8/site-packages/setuptools/_distutils/cmd.py:66: SetuptoolsDeprecationWarning: setup.py install is deprecated.
!!

        ********************************************************************************
        Please avoid running ``setup.py`` directly.
        Instead, use pypa/build, pypa/installer or other
        standards-based tools.

        See https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html for details.
        ********************************************************************************

!!
  self.initialize_options()
In file included from /home/linxq/.conda/envs/seg38/lib/python3.8/site-packages/numpy/core/include/numpy/ndarraytypes.h:1940,
                 from /home/linxq/.conda/envs/seg38/lib/python3.8/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,
                 from /home/linxq/.conda/envs/seg38/lib/python3.8/site-packages/numpy/core/include/numpy/arrayobject.h:5,
                 from imagecodecs/_aec.c:1215:
/home/linxq/.conda/envs/seg38/lib/python3.8/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: #warning "Using deprecated NumPy API, disable it with " "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
   17 | #warning "Using deprecated NumPy API, disable it with " \
      |  ^~~~~~~
imagecodecs/_aec.c:1222:10: fatal error: libaec.h: No such file or directory
 1222 | #include "libaec.h"
      |          ^~~~~~~~~~
compilation terminated.
error: Setup script exited with error: command '/usr/bin/gcc' failed with exit code 1

解决方法

重新安装 imagecodecs 库:

pip install imagecodecs==2021.4.28
conda install -c conda-forge imagecodecs

返回:

...
Using /home/linxq/.conda/envs/seg38/lib/python3.8/site-packages
Finished processing dependencies for cellpose==3.0.0

【ref】install imagecodecs on mac big sur

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值