如何在没有子导入的情况下导入模块

How to import a module without sub-imports

我正在构建一个模块,但我很难理解哪个是避免工作区污染的最佳实践。

示例代码

我的模块是:

aModule\
    __init__.py
    aSubModule.py
    someFunctions.py

文件内容为:

init.py

from .someFunctions import function1, function2
from aModule import aSubModule

someFunctions.py

from numpy import exp,log,sqrt

def function1():
    print('function1: Hello World!')
    
def function2():
    print('function2: Hello ' + aUtilityFunction())
    
def aUtilityFunction(): #This should not be imported
    return 'World!'

aSubModule.py

from numpy import exp,log,sqrt

def function3():
    print('I am function 3')
    
def function4():
    print('I am function 4')

问题

做的时候

import aModule

我希望能够访问

aModule.function1()
aModule.function2()
aModule.aSubModule.function3()
aModule.aSubModule.function4()

但是我也有以下不良行为:

问题 1

文件someFunctions.py作为子模块导入。换句话说,我可以从 aModule.function1 和 aModule.someFunctions.function1 访问 function1 。在我看来,这是混乱的。 我找到的唯一解决方案是重命名文件 _someFunctions.py 。前导下划线现在告诉 Python 不要导入它。这看起来不错,但我不确定这是否被认为是好的做法。

问题 2

在aModule.aSubModule下导入函数exp、log和sqrt。我想访问 aSubModule doing

中的函数
aModule.aSubModule.function3()

但我想避免在 aModule.aSubModule

中包含 exp、log 和 sqrt

这是因为在我正在处理的“真实”子模块中,我只有 3-4 个与用户相关的函数,但有 10-15 个以上的导入。因此,当我尝试 tab-complete

aModule.aSubModule.<tab>

弹出大约 20 个条目,其中只有 3-4 个是相关的。

我找不到好的方法,但黑客攻击是可能的。诀窍是任何以下划线开头的标识符都不会被帮助系统使用而不是用于 tab 自动完成,即使它是一个模块标识符。所以为了避免自动访问不必要的标识符,你可以有包含 private modules

的包
aModule\
    __init__.py
    _someFunctions.py
    aSubModule\
        __init__.py
        _aSubModule.py

aModule __init__.py的内容:

from ._subFunctions import f1, f2
from . import aSubModule

aSubModule __init__.py的内容:

from ._aSubModule import f3, f4

我必须承认它相当老套,而且不是很 Pythonic。也许自定义导入器会导致更清晰的代码,但我找不到通过 importlib 模块的方法。

我的结论是,Pythonic 方式可能不是试图隐藏通过模块导入的名称,而是只在当前命名空间中导入您需要的名称。