第一次尝试创建python库。被 modulenotfounderror 困扰

Posted

技术标签:

【中文标题】第一次尝试创建python库。被 modulenotfounderror 困扰【英文标题】:Attempting to create a python library for the first time. Getting plagued with modulenotfounderror 【发布时间】:2021-12-01 05:44:06 【问题描述】:

创建一个简单的客户端库,以便使用我的 api 的人可以轻松使用它。对 python 相当陌生(3 个月),以前从未创建过我自己的模块/库/包。我看了很多非常简单的教程,并认为我做得很好。但是,尽管按照信中的说明进行操作,但我收到了一个未找到模块的错误。这是基本格式(注意,由于工作场所政策,我已经替换了大多数文件、类和方法的名称,但是它应该对结构没有影响

python-sdk (the name of the repository)
 |    ⊢src (my boss wants everything wrapped inside of a src directory)
 |    |    ⊢library (this will be the package that is imported by users)
 |    |    |    ⊢__init__.py
 |    |    |    ⊢filename.py
 |    |    |    |    ⊢class myclass1
 |    |    |    |    |    ⊢staticmethod()
 |    |    |    |    ⊢class myclass2
 |    |    |    |    |    ⊢method()
 |    |    test-app.py

当前文件名包含 2 个类(非常简单的类,只是为了测试),名为 myclass1 和 myclass2。每个类都包含一个方法,现在只需添加或乘以 2 个值。我这样做只是为了学习创建库。知道后面代码怎么实现了。

初始化文件包含以下内容:

from filename import myclass1, myclass2

测试应用很简单:

from library import myclass1, myclass2
print(myclass1.staticmethod1(15, 20))

myclassinstance = myclass2(15, 20)

print(myclassinstance.method())

根据堆栈跟踪,它从 test-app.py 的第一行开始,它看到库的导入,因此它转到库中的 init 文件。然后在 init 的第 1 行,它看到了 from filename import myclass1, myclass2 并对文件名感到愤怒。

上面写着:

/home/sexmaster/PycharmProjects/python-sdk/venv/bin/python /home/sexmaster/PycharmProjects/python-sdk/src/test-app.py
Traceback (most recent call last):
  File "/home/sexmaster/PycharmProjects/python-sdk/src/test-app.py", line 1, in <module>
    from library import myclass1, myclass2
  File "/home/derek1st/PycharmProjects/python-sdk/src/library/__init__.py", line 1, in <module>
    from filename import class1, class2
ModuleNotFoundError: No module named 'filename'

Process finished with exit code 1

有什么猜测吗?这应该是非常基本的。我不知道出了什么问题。我在 pycharm 中没有任何价值。

【问题讨论】:

【参考方案1】:

由于您尝试从 __init__ 文件进行相对导入,因此您应该在文件名之前添加一个句点,如下所示。

from .filename import myclass1, myclass2

然后你可以从包中导入:

from library import myclass1, myclass2

以下是所要求的解释:

当我们在包中使用相关模块时,指定完整路径有点多余,因为我们知道父模块的名称,所以相对导入基本上是一种说法,即找到一个类、函数或模块它是相对于当前模块定位的。

假设我们有以下包:

parent_directory/
      main.py
      ecommerce/
          __init__.py
          database.py
          products.py
          payments/
              __init__.py
              paypal.py
              stripe.py

如果我们在 products 模块中工作并且我们想从它旁边的 database 模块中导入 Database 类,我们使用相对导入:

from .database import Database

database前面的句号:使用当前包里面的database模块。

如果我们正在编辑 ecommerce/payments 包内的 paypal 模块,并且我们想使用父包内的 database 模块(电子商务包) 这将按如下方式完成:

from ..database import Database

我们可以使用更多的句点在层次结构中更上一层楼,也可以从一侧向下备份另一侧(留给读者练习)

现在,请记住 __init__.py 文件将目录定义为包,它可以包含任何变量或类声明,它们将作为包的一部分提供,因此在我们的示例中,如果 ecommerce/__init__.py 文件包含此行:

from .database import db

然后我们可以使用下一个导入从 main.py 或任何其他文件中访问 db 属性:

from ecommerce import db

我个人建议不要在 __init__ 文件中添加太多代码,因为 Python 开发人员实际上并不期望在其中发生逻辑。

在您的特定情况下,您的 __init__.py 文件与文件名模块相关,这就是需要进行相对导入的原因。不过,您也可以直接在 test-app.py 中执行绝对导入,如下所示:

from library.filename import myclass1, myclass2

两种导入方式都是正确的,使用一种让你的代码看起来更优雅的方式

进一步阅读:

D. Phillips,Python 3 面向对象编程 3 版

【讨论】:

首先,这行得通,非常感谢。但更重要的是,您能否跟进一下为什么有效。我遵循的教程不包括句点。 “相对导入”我假设您的意思是因为它是从我的项目内的某个位置而不是从外部库或其他东西导入的。这些教程都是没有句号的“相对”进口。我以为linux中的时间段只隐藏了一个文件。有什么意义? 已经有了解释,很高兴它有帮助

以上是关于第一次尝试创建python库。被 modulenotfounderror 困扰的主要内容,如果未能解决你的问题,请参考以下文章

Python标准库概览

运行python app时,MySql Access被拒绝[Ubuntu 1604 / NGINX / uWSGI]

在Windows上的Ubuntu上用Bash更新Python库

为 C 库生成 Python SWIG 绑定时未定义的符号

Python pip --index-url 不限制存储库搜索

在 Xcode 5 Mavericks Server 上创建 Bot 时被要求提供存储库凭据