python - 我应该从 __dir__ 方法中隐藏 python 模块中依赖项的导入吗?

标签 python python-3.x python-import python-module

我正在制作一个 Python 分发包,其中包含一个包含多个模块(一个文件夹,多个文件)的导入包。该包具有在模块中导入的依赖项。当用户从导入包中导入模块时,他们还可以访问在函数外部导入的依赖项。我找到了解决方法,但我不确定这是否是个好主意。

模块 joke.py 的选项 A

from markdown import markdown

def joke():
    return markdown("The Funniest Joke in the World")

模块 joke.py 的选项 B

def joke():
    from markdown import markdown
    return markdown("The Funniest Joke in the World")

在交互模式下使用 A

>>> import joke
>>> joke.joke()
'The Funniest Joke in the World'
>>> dir(joke)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'joke', 'markdown']
>>> joke.markdown("Not funny")
'<p>Not funny</p>'

B在交互模式下的使用

>>> import joke
>>> dir(joke)
['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__file__', '__cached__', '__builtins__', 'joke', 'markdown']
>>> joke.markdown("Not funny")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'joke' has no attribute 'markdown' 

问题

我不想将依赖项暴露给用户,这意味着选项 B 更好。但是,如果所有导入都需要在类或函数内部进行,代码就会变得困惑。有没有更好的选择来实现 B 中的功能而不会使导入变得困惑?

我查看了一些包,看是否可以使用 dir() 找到它们的任何依赖项,但感觉有点不知所措,因为我不知道它们有哪些依赖项或如何找到它们的依赖项。

最佳答案

从 Python 3.7 开始,您可以定义一个 module-level __dir__ function它将用于生成 dir(module) 的结果:

def __dir__():
    return ['joke']

这可以与处理 from module import * 导入的 __all__ 结合使用:

__all__ = ['joke']

def __dir__():
    return __all__

请注意,用户仍然可以访问这些依赖包,即 joke.markdown 仍然有效。如果你真的想限制这个,你也可以定义一个模块级的__getattr__:

def __getattr__(name):
    if name not in __all__:
        raise AttributeError(name)
    return globals()[name]

关于python - 我应该从 __dir__ 方法中隐藏 python 模块中依赖项的导入吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61984376/

相关文章:

python - 如何检查模块是否已导入?

python - 使用 cron 启动 python 脚本并将打印输出到文件

python - 如何指定颜色条范围并保持它而不考虑绘图值

python - 如何将 shell 命令输出重定向到 Python 脚本输入?

python - 基于列索引的 Sort_values

python - 如何使用子包正确打包Python3应用程序

python - 无法在 Windows 10 上导入 pywinauto

python - 在 Python 中清除用户创建的变量

python - Pytest 断言方法的返回值

python - 在 Python 中正确导入模块