如何在创建 Python 包时调用库的直接导入

How to call direct imports of libraries in the creation of a Python package

背景

我正在尝试创建一个具有半复杂结构的 Python 包。我之前发布过几个包,因为它们很简单,所以我把所有需要的 classes 和函数放在 __init__.py 本身。例如,我的一个简单包的文件结构是:

Package/
    venv # my virtual environment
    package-name/
        __init__.py
    setup.py # with setuptools, etc.

示例包中的示例 __init__.py 文件为:

# __init__.py from a sample simple package
import requests

class User:
    def __init__(self, something):
        self.something = requests.get(url).json()['something']

    def do_something(self):
        return float(self.something) * 10

像这样的示例包是基本的,只需要User class,这就足够了。在使用 pip 安装包时,使用 import package-name 可以调用 User 对象。

# random computer with simple package installed
import package_name

api = package_name.User()

这很好用。

问题

像我正在处理的更复杂的包不能直接在 __init__.py 文件中包含所有 classes 和函数。结构如下:

Package/
    venv # my virtual environment
    package-name/
        __init__.py
        related.py
        something.py
    setup.py

问题是我不太明白如何让 related.pysomething.py 的内容隐式工作。隐含地,我的意思是当用户执行 import package_name 时,他们可以使用 package_name.attribute 访问任何文件的任何属性,无论它在 __init__.pyrelated.pysomething.py.

目前,如果我这样构建 __init__.py 文件:

# complex package __init__.py
from package_name import related
from package_name import something

用户仍然需要调用relatedsomething作为package_name的属性:

# random computer user file with package_name installed
import package_name

x = package_name.related.x()
y = package_name.something.y()

我希望他们能够改为这样做:

# random computer user file with package_name installed
import package_name

x = package_name.x()
y = package_name.y()

无需自己在自己的计算机上编写:from package_name import relatedfrom package_name import something

很抱歉问了这么长的问题,但我想尽可能清楚地说明我的问题,因为有很多变动的部分。

__init__.py 中可用的任何名称都将在 import package_name 中用作 package_name.whatever。因此,如果你想让子模块的名称可用,你可以在你的 __init__.py.

中执行 from package_name.related import x (或 from .related import x