2014-09-28 66 views
1

这是一个概念性的问题,而不是一个实际的问题,我想问一个伟大的互联网大群人的反馈意见。Python - 我应该使用下划线别名吗?

# Module a: 
import b 
__all__ = ['f'] 
f = lambda: None 

这可以让你做到这一点:

我们都知道进口模块该模块的命名空间最终

import a 
a.b # <- Valid attribute 

有时候,这是伟大的,但大部分进口的副作用您的模块提供的功能。在上面的例子中,我并不是想将b作为a调用者的有效接口。

为了抵消我们做:

import b as _b 

这标志着进口为私有。但是我无法在任何地方找到这种做法,PEP8也没有谈到使用别名来标记进口是私人的。所以我认为这不是通常的做法。但是从某个角度来说,我认为它在语义上更清晰,因为它清除了模块中暴露的部分,只留下了实际意义要暴露的相关接口。使用自动完成的IDE工作,它使得建议的列表更加轻薄。

我的问题归结为如果你已经看到使用该模式?它有名字吗?哪些论据会反对使用它?

我还没有成功使用__all__功能来隐藏b导入。我使用的是PyCharm,没有看到自动完成列表的变化。

E.g.从一些模块,我可以这样做:

import a 

并自动完成框同时显示bf

回答

2

虽然马亭皮特斯说,没有人实际使用下划线隐藏模块导入,这是不完全正确。这种技术的痕迹可以很容易地在Python的标准库本身中看到(请参阅related question)。让我们来看看它:

$ git clone --depth 1 [email protected]:python/cpython.git 
$ cd cpython/Lib 
$ find -iname '*.py' | xargs grep 'as \+_' | wc -l 
183 
$ find -iname '*.py' | xargs grep '^import' | wc -l 
4578 

因此,所有进口的约4%的下划线前缀 - 不是多数,但还远没有“任何人”。在numpymatplotlib包中也有一些示例。

对我来说,这种导入下划线是唯一的导入模块的正确方式,而不公开暴露。不幸的是,它完全破坏了代码外观,所以很多开发人员都避免使用它。但它比__all__方法有一些优点:

  • 图书馆用户可以决定名称是否是私人的,只需查看名称就可以查阅文档。展望__all__而不是足以告诉公众,因为一些公开名称可能没有在那里列出。
  • 不需要维护代码实体名称的重构不友好列表。

的结论,既_name__all__只是普通的邪恶,但实际上需要固定的东西是Python的模块系统,“simple is better than complex”口头禅的印象设计。例如,比较模块在Haskell中的行为方式。

UPD:
它看起来像PEP-8已经在其“Public and internal-interfaces”部分已经回答了这个问题:

即使__all__适当设置,内部接口(封装,模块,类,函数,属性或其他名称)仍应以前导下划线作为前缀。

2

没有人使用该模式,它没有命名。

这是因为适当方法使用的是明确标注与__all__变量导出的名称。 IDE将遵循这个变量,像help()这样的工具。

引述import statement documentation

公共名由被检查模块的名为__all__变量的命名空间确定的模块定义;如果定义了它,它必须是由该模块定义或导入的名称的字符串序列。 __all__中给出的名称都被认为是公开的,并且必须存在。如果未定义__all__,则公用名称集合将包含模块名称空间中的所有名称,该名称不以下划线字符开头('_')。 __all__应该包含整个公共API。它旨在避免意外导出不属于API的项目(,例如在模块中导入和使用的库模块)。

(Emphasis mine)。

另见Can someone explain __all__ in Python?

+0

我想我是在一些误解之下,我以为'__all__'只涉及'from一个import *'模式?这是我从链接中得出的结论,也是我通过SO搜索过的。 在PyCharm当我做一个'__all__'进入它不会改变自动完成框,当我做一个正常的'进口了' 例如为: 模块: 从。进口b __all__ = [ 'F'] F =拉姆达:无 (模块B是空的)从另一个模块我可以做现在 :从 。导入一个 自动完成框显示'b'和'f'。 – 2014-09-28 00:44:57

+1

@JonLauridsen:'from modulename import *'模式是'__all__'的一个*用例。如果PyCharm仍然为'__all__'中未列出的名称提供自动完成,这可能被认为是PyCharm中的一个错误。 – 2014-09-28 00:49:13

+0

嗯,那样做是的.. 好吧,我创建了一个缺陷@ http://youtrack.jetbrains.com/issue/PY-14022,我们将看到会发生什么!谢谢。 – 2014-09-28 00:55:55