如何使用 __init__.py 创建干净的 API?

问题描述 投票:0回答:1

问题描述:

我正在尝试为我的团队创建一个本地 API。我想我大致了解 _init_.py 的机制。假设我们有以下包结构:

API/
├── __init__.py         # Top-level package init file
└── core/               
    ├── __init__.py     # Core module init file
    ├── calculator.py   
    └── exceptions.py   

现在,如果我使用空的 _init_.py 文件构建 API,然后在脚本中导入 API,我将无法执行以下操作:

import API
API.core
API.core.calculator

因为子模块还没有专门导入。我需要做的是将以下内容添加到我的顶级 _init_.py:

from . import core

并将以下内容放入我的核心模块_init_.py:

from . import calculator
from . import exceptions

现在,当我这样做时,我在calculator.py或exceptions.py中进行的所有导入(例如numpy或pandas)实际上都可以通过我的包获得,如下所示:

API.core.calculator.numpy

问题 1:防止导入的库通过我的 API 显示的最佳实践是什么?

在同一主题上,假设我想直接通过 core 关键字访问计算器.py 函数(假设 _all_ 变量已安全设置)。然后我可以将以下内容添加到我的核心模块中_init_.py

from .calculator import *
from .exceptions import *

然后我可以这样做:

API.core.my_function()

但是话又说回来,我也可以同时调用 API.core.calculator.my_function(),这可能会让用户感到困惑。

2.如何防止导入的函数通过我的包名称和模块名称可用?

我尝试混合方法,但没有结果,请帮忙!

python api import init
1个回答
0
投票

典型的最佳实践是在每个子模块中定义一个 [

__all__
] (https://docs.python.org/3/tutorial/modules.html#importing-from-a-package) 列表您希望子模块导出的名称,以便父模块可以使用星号导入仅导入这些名称。

因此,在您的示例中,您的

calculator.py
看起来像:

import numpy

__all__ = ['my_function']

def my_function(): ...

然后

core.py
将星形导入
calculator
导出的内容:

from .calculator import *

然后您可以执行以下操作:

API.core.my_function()

但不是:

API.core.numpy
API.core.calculator.numpy
© www.soinside.com 2019 - 2024. All rights reserved.