如何使用简单的“导入”语句使 python 函数和 类 在系统范围内可用

How to have python functions and classes available system-wide with an easy `import` statement

简介

我想我会尝试制作一个 python 模块以使我的一些库和函数在系统范围内可用。 Google 和 StackExchange 提供了充足的 "solutions" 和操作方法。但出于某种原因,其中 none 似乎对我有用。显然,我做错了什么。但经过几天的反复试验,我决定向你们展示我所拥有的,并让你们向我指出明显的错误 ;-) 非常感谢你们的帮助。

我有什么

我的 GitHub 项目目录包含这棵树:

$ tree /tmp/mausy5043-common-python
/tmp/mausy5043-common-python
├── docs
├── gitforcepull
├── LICENSE
├── mausy5043funcs
│   └── __init__.py
├── mausy5043libs
│   ├── __init__.py
│   ├── libdaemon3.py
│   └── libsmart3.py
├── README.md
├── setup.py
└── tests

libsmart3.py 是一个提供 class SmartDisk(): 的 python 脚本。 __init__.py 脚本都是空的。 libdaemon3.py 是包含另一个 class 的脚本。它有同样的问题,但我将在此处使用 libsmart3 模块作为示例。

我安装这个项目如下:

$ sudo python3 setup.py install
running install
running build
running build_py
creating build
creating build/lib
creating build/lib/mausy5043libs
copying mausy5043libs/libdaemon3.py -> build/lib/mausy5043libs
copying mausy5043libs/libsmart3.py -> build/lib/mausy5043libs
running install_lib
copying build/lib/mausy5043libs/libsmart3.py -> /usr/local/lib/python3.4/dist-packages/mausy5043libs
copying build/lib/mausy5043libs/libdaemon3.py -> /usr/local/lib/python3.4/dist-packages/mausy5043libs
byte-compiling /usr/local/lib/python3.4/dist-packages/mausy5043libs/libsmart3.py to libsmart3.cpython-34.pyc
byte-compiling /usr/local/lib/python3.4/dist-packages/mausy5043libs/libdaemon3.py to libdaemon3.cpython-34.pyc
running install_egg_info
Removing /usr/local/lib/python3.4/dist-packages/mausy5043_common_python-0.1dev.egg-info
Writing /usr/local/lib/python3.4/dist-packages/mausy5043_common_python-0.1dev.egg-info

什么不起作用

现在我想在另一个 python 脚本中使用这个 class SmartDisk()。为此,我希望(希望)我能够直接导入 class——感谢 __init__py 的存在——因此:

$ python3
Python 3.4.2 (default, Oct 19 2014, 13:31:11)
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from mausy5043libs import SmartDisk
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name 'SmartDisk'
>>>

>>> from libsmart3 import SmartDisk
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named 'libsmart3'
>>>

我怎么不想让它工作

的作用是:

>>> from mausy5043libs.libsmart3 import SmartDisk

但这不是广告宣传的方式(参考:http://mikegrouchy.com/blog/2012/05/be-pythonic-__init__py.html

我还尝试了什么

我尝试在 mausy5043libs/__init__.py 中添加 import libsmart3。没用。

我在 mausy5043libs/__init__py 中添加了 from libsmart3 import SmartDisk。不开心。

假设 python 需要它,我在项目根目录中添加了一个空的 __init__.py。没有帮助。

编辑 所做的更改:根据@user2357112

的建议更改为 mausy5043libs/__init__py
$ cat mausy5043libs/__init__.py
from .libsmart3 import SmartDisk 
$ sudo python3 setup.py install 
[... output removed ...] 
$ python3
Python 3.4.2 (default, Oct 19 2014, 13:31:11)
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from mausy5043libs import SmartDisk
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name 'SmartDisk'

EDIT 2:事实证明@user2357112 does 提供的解决方案确实有效。显然,我有一个小疏忽。 setup.py py_modules 列表中缺少条目 mausy5043libs/__init__

您完全误读了您正在处理的来源。如果你希望能够直接从mausy5043libs包中导入SmartDisk,那么mausy5043libs/__init__.py需要导入SmartDisk:

# in mausy5043libs/__init__.py
from .libsmart3 import SmartDisk

然后包的用户可以按照您想要的方式导入它:

# in code that wants to use SmartDisk
from mausy5043libs import SmartDisk

您链接的文章在 "What goes in __init__.py?" 下包含此信息,尽管它们使用 Python 3 之前的隐式相对导入语法。