我应该从 __dir__ 方法中隐藏 python 模块中的依赖项导入吗?
Should I hide imports of dependencies in a python module from the __dir__ method?
我正在制作一个 Python 分发包,其中包含一个包含多个模块(一个文件夹,多个文件)的导入包。该包具有在模块中导入的依赖项。当用户从导入包中导入模块时,他们还可以访问在函数外部导入的依赖项。我找到了解决方法,但我不确定这是否是个好主意。
模块的选项 A joke.py
from markdown import markdown
def joke():
return markdown("The Funniest Joke in the World")
模块选项 B joke.py
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 分发包,其中包含一个包含多个模块(一个文件夹,多个文件)的导入包。该包具有在模块中导入的依赖项。当用户从导入包中导入模块时,他们还可以访问在函数外部导入的依赖项。我找到了解决方法,但我不确定这是否是个好主意。
模块的选项 A joke.py
from markdown import markdown
def joke():
return markdown("The Funniest Joke in the World")
模块选项 B joke.py
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]