You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用__init__.py构建简洁API并解决暴露相关问题

解决方案

问题1:防止依赖库通过API暴露的最佳实践

有几种可靠的方式解决这个问题:

  • 只导出需要的接口,不暴露内部模块:不要在core/__init__.py里导入整个calculator或exceptions模块,而是直接从这些模块导入你想对外提供的函数、类或异常。示例:

    # core/__init__.py
    from .calculator import add_numbers, multiply_numbers  # 仅导入需要的函数
    from .exceptions import CalculationError, InvalidInputError  # 仅导入需要的异常
    

    这种方式下,用户无法通过API.core.calculator访问到内部模块,自然也看不到模块里导入的numpy、pandas等依赖。

  • 用__all__明确限定对外导出内容:如果习惯用from .calculator import *的写法,在calculator.py里定义__all__变量,只列出你想对外暴露的对象,这样通配符导入只会导入指定内容,不会带入库依赖:

    # calculator.py
    import numpy as np
    
    __all__ = ['add_numbers', 'multiply_numbers']
    
    def add_numbers(a, b):
        return np.add(a, b)
    

    同时在core/__init__.py里使用from .calculator import *,但因为calculator.py的__all__限制,只会导入指定函数,且用户看不到calculator模块本身(只要不在core/__init__.py里导入calculator模块)。

  • 将依赖设为模块私有(辅助手段):在模块内部导入依赖时,给依赖名加上下划线前缀,比如import numpy as _np。按照Python惯例,下划线开头的名称是内部私有元素,用户不应访问。不过这只是约定而非强制限制,建议结合前两种方法使用。

问题2:避免函数同时通过包名和模块名访问

核心思路是不要把内部模块(如calculator、exceptions)导入到父包的命名空间中,只把需要的函数/类直接导入到父包层级:

  1. 在core/__init__.py里,仅导入具体的函数和异常,不导入内部模块:
    # core/__init__.py
    from .calculator import my_function
    from .exceptions import CalculationFailed
    
  2. 顶层API/__init__.py里只导入core:
    # API/__init__.py
    from . import core
    

这样用户只能通过API.core.my_function()调用函数,API.core.calculator这个路径根本不存在,不会出现重复访问的情况。

如果需要保留内部模块结构但不想让用户访问,也可以导入模块后用del语句移除引用:

# core/__init__.py
from . import calculator
from .calculator import my_function
del calculator  # 移除模块引用,用户无法访问API.core.calculator

不过这种方式不如直接导入目标对象简洁,更推荐第一种方案。


内容的提问来源于stack exchange,提问作者Loris Constantin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 06:05:13