这是一个概念性问题,而不是一个实际问题,我想向广大互联网群众寻求反馈。
我们都知道导入的模块最终位于该模块的命名空间中:
# Module a:
import b
__all__ = ['f']
f = lambda: None
Run Code Online (Sandbox Code Playgroud)
这允许你这样做:
import a
a.b # <- Valid attribute
Run Code Online (Sandbox Code Playgroud)
有时这很好,但大多数导入都是模块提供的功能的副作用。在上面的示例中,我并不是b要向a.
为了抵消这个问题,我们可以这样做:
import b as _b
Run Code Online (Sandbox Code Playgroud)
这将导入标记为私有。但我找不到任何地方描述的这种做法,PEP8 也没有讨论使用别名将导入标记为私有。所以我认为这不是常见的做法。但从某个角度来看,我想说它在语义上肯定更清晰,因为它清理了模块的暴露部分,只留下您实际想要暴露的相关接口。使用具有自动完成功能的 IDE 可以使建议列表变得更加精简。
我的问题归结为您是否见过这种模式的使用?它有名字吗?什么论据会反对使用它?
我没有成功使用__all__隐藏b导入的功能。我正在使用 PyCharm,但没有看到自动完成列表发生变化。
例如,从某个模块我可以执行以下操作:
import a
Run Code Online (Sandbox Code Playgroud)
自动完成框显示b和f。
虽然 Martijn Pieters 说没有人真正使用下划线隐藏模块导入,但这并不完全正确。这种技术的痕迹可以在Python的标准库本身中很容易地看到(参见相关问题)。让我们检查一下:
\n\n$ git clone --depth 1 git@github.com:python/cpython.git\n$ cd cpython/Lib\n$ find -iname \'*.py\' | xargs grep \'as \\+_\' | wc -l\n183\n$ find -iname \'*.py\' | xargs grep \'^import\' | wc -l\n4578\nRun Code Online (Sandbox Code Playgroud)\n\n因此,大约 4% 的导入都是以下划线前缀的 \xe2\x80\x94 ,虽然不是大多数,但还远远低于 \xe2\x80\x9cno one\xe2\x80\x9d 。numpy和包中也有一些示例matplotlib。
对我来说,这种导入下划线是导入模块而不将其公开的唯一正确方法。不幸的是,它完全破坏了代码的外观,因此许多开发人员避免使用它。但与该方法相比,它有一些优点__all__:
__all__不足以区分私人和公共名称,因为某些公共名称可能未列出。总而言之, 和_name都是__all__纯粹的邪恶,但真正需要修复的是Python的模块系统,它是在\xe2\x80\x9csimple优于complex\xe2\x80\x9d口头禅的印象下设计的。例如,与 Haskell 中模块的行为方式进行比较。
UPD:
\n看起来 PEP-8 已经在其\xe2\x80\x9cPublic 和内部接口\xe2\x80\x9d部分回答了这个问题:
\n\n即使
\n__all__设置正确,内部接口(包、模块、类、函数、属性或其他名称)仍应以单个前导下划线为前缀。
| 归档时间: |
|
| 查看次数: |
1304 次 |
| 最近记录: |