4

我创建了两个模块,一个与

def _func():
    print "hi"

和另一个

def func():
    print "hi"

当我在包含第一个功能的模块上使用帮助功能时,帮助模块不显示此功能。与此函数显示在帮助输出中的第二个示例相反。除了使用帮助功能之外,还有什么功能上的区别吗?

4

4 回答 4

13

是的,在功能方面存在(诚然微妙的)差异。假设您有一个模块A.py

foo = 1
_bar = 2

观察:

>>> from A import *
>>> foo
1
>>> _bar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name '_bar' is not defined

如果您这样做,则默认行为import *是不导入带前导下划线的成员。__all__您可以通过指定一个列表来覆盖该行为:

__all__ = ['foo', '_bar']

foo = 1
_bar = 2

现在:

>>> from A import *
>>> (foo, _bar)
(1, 2)

顺便说一句,__all__还覆盖了help()or显示的成员列表pydoc

$ pydoc A | cat
 ...
DATA
    __all__ = ['foo', '_bar']
    _bar = 2
    foo = 1
 ...
于 2012-04-06T14:38:04.943 回答
3

以“_”开头的模块级名称有所不同:当您使用时它们不会被导出from module import *-

可以通过让模块有一个名为的列表来覆盖此行为,__all__该列表列出了您要从模块中导出的所有属性。

尽管:

import module
module._func

将毫无区别地工作。正如其他答案所暗示的那样:“_”是一个指示名称应该保留给模块/类/API的私人使用-但是,在“从模块导入*”和自动帮助的唯一情况下-作为在您的情况下,口译员确实会以不同的方式对待。

于 2012-04-06T14:41:00.433 回答
3

这是一个 python 约定,任何以下划线开头的名称都不会被视为公共 api 的一部分,因此包含以下划线开头的函数的模块或类的用户不会通过正常访问被告知这些函数的存在。当然,由于它只是一个约定,因此可以绕过它,但作为一般经验法则,您可以考虑将任何以下划线开头的内容隐藏在模块/类之外的代码中。

以下是来自 python 文档的更多信息:http: //docs.python.org/tutorial/classes.html#tut-private

于 2012-04-06T14:39:29.670 回答
2

下划线是一种约定,通常用于表示模块或类的私有成员。

于 2012-04-06T14:34:56.873 回答