微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

具有依赖项初始化错误的自定义程序包:ModuleNotFoundError或ImportError

如何解决具有依赖项初始化错误的自定义程序包:ModuleNotFoundError或ImportError

我正在创建一个具有以下结构的自定义程序包:

test_package
    │   README.md
    │   setup.py
    │
    ├───my_package
    │       my_package.py
    │       __init__.py
    │
    └───tests
            tests.py

我的程序包依赖pygdbmi,因此我将其添加到所需依赖项列表中。

我正在使用__init__.py导入模块

__init__.py

from .my_package import my_class

__version__ = '0.0.1'
__title__ = 'my_package'

我的课是:

my_package.py

from pygdbmi.gdbcontroller import GdbController

class my_class:
    def __init__(self):
        print("my_class!!")
        self.gdbmi = GdbController()

问题是,当我运行python setup.py install clean时,我得到了ModuleNotFoundError

python setup.py install clean
Traceback (most recent call last):
  File "setup.py",line 2,in <module>
    import my_package
  File "c:\test_package\my_package\__init__.py",line 1,in <module>
    from .my_package import my_class
  File "c:\test_package\my_package\my_package.py",in <module>
    from pygdbmi.gdbcontroller import GdbController
ModuleNotFoundError: No module named 'pygdbmi

这很明显,因为__init__正在导入my_package,但由于我尚未安装pygdbmi而中断了。

我试图通过从__init__.py删除导入来解决此问题:

__version__ = '0.0.1'
__title__ = 'my_package'

它可以正确安装,但是现在我无法导入我的软件包。当我尝试运行一些测试时:

python tests.py
Traceback (most recent call last):
  File "tests.py",line 3,in <module>
    from my_package import my_class
ImportError: cannot import name 'my_class' from 'my_package' (C:\Users\lalalala\AppData\Local\Continuum\anaconda3-32\lib\site-packages\my_package-0.0.1-py3.7.egg\my_package\__init__.py)

我该如何解决?我想保留定义版本等的__init__结构,因为这似乎是Python的方式。

非常感谢!

setup.py

import setuptools
import my_package

with open("README.md","r") as fh:
    long_description = fh.read()

setuptools.setup(
    # Project information
    name=my_package.__title__,version=my_package.__version__,long_description_content_type="text/markdown",packages=setuptools.find_packages(),install_requires=["pygdbmi"],python_requires='>=3.7',# Tests
    test_suite='tests'
)

my_package.py

from pygdbmi.gdbcontroller import GdbController

class my_class:
    def __init__(self):
        print("my_class!!")
        self.gdbmi = GdbController()

tests.py

import unittest

from my_package import my_class

class some_test(unittest.TestCase):
    def test_constructor(self):
        self.assertIsNotNone(my_class())

if __name__ == '__main__':
    unittest.main()

解决方法

我该如何解决?我想保留定义版本等的__init__结构,因为这似乎是Python的方式。

不是,名称和版本是程序包元数据,不属于源代码。它属于您的程序包定义,在您的情况下表示setup.py

您的__init__.py应该反过来工作,并通过与python环境及其自身安装进行交互来获取其信息:

from importlib import metadata

# this works,but usually people just write the name as a string here.
# not 100% DRY,but it's not like the package name could ever change
__title__ = __name__
# if you're stuck on python 3.7 or older,importlib-metadata is a 
# third-party package that can be used as a drop-in instead
__version__ = metadata.version(__title__)

最重要的要点是,不要将代码导入到构建脚本中。它可以1)造成讨厌的鸡蛋问题,除非已经安装了较旧的版本,否则无法构建您的代码,以及2)将所有运行时依赖项转换为内置时依赖性,这就是您要执行的操作体验。

您也许可以解决这两个问题,但是更简单的方法是按照上述方法设置您的包裹数据,而从一开始就不要解决这个问题。

,

这听起来令人失望,但我几乎会放弃并执行以下操作:

  • pygdbmi删除install_requires
  • pygdbmi放入requirements.txt
  • from pygdbmi.gdbcontroller import GdbController包装在try...except块中,这将显示一条有用的消息,告诉用户如果他们想使用该软件包,则需要手动安装pygdbmi;然后重新引发异常
  • 在任何安装说明或部署脚本中,只需在pip install -r requirements.txt之前添加python setup.py install

据我所知,这并不是一种非常常见的做法-我遇到了一些PyPI的软件包,这些软件包需要我手动安装其必备软件。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?