我正在编写一个由两部分组成的小型Python模块:
首先,我决定通过使用它在函数内部定义它来“隐藏”这个实现类,但这会妨碍可读性,如果多个函数重用同一个类,则不能使用它。
那么,除了评论和文档字符串之外,还有一种机制可以将类标记为“私有”或“内部”吗?我知道下划线机制,但据我所知它只适用于变量,函数和方法名称。
答案 0 :(得分:143)
使用单个下划线前缀:
class _Internal:
...
这是'内部'符号的官方Python约定; “from module import *”不会导入以下划线为前缀的对象。
答案 1 :(得分:58)
简而言之:
您无法强制执行隐私。 Python中没有私有类/方法/函数。至少,不像其他语言那样严格的隐私,例如Java。
您只能表明/建议隐私。这符合一项惯例。将类/函数/方法标记为私有的python约定是以_(下划线)为前缀。例如,def _myfunc()
或class _MyClass:
。您还可以通过使用两个下划线(例如:__foo
)为方法添加前缀来创建伪隐私。您无法直接访问该方法,但您仍然可以使用classname通过特殊前缀来调用它(例如:_classname__foo
)。因此,您可以做的最好的事情是表明/建议隐私,而不是强制执行。
Python在这方面就像perl。为了解释Perl书中关于隐私的着名路线,我们的理念是,你应该留在起居室,因为你没有被邀请,而不是因为它是用霰弹枪保护的。
了解更多信息:
答案 2 :(得分:35)
定义__all__
,您要导出的名称列表(see documentation)。
__all__ = ['public_class'] # don't add here the 'implementation_class'
答案 3 :(得分:9)
我有时使用的模式是:
定义一个类:
class x(object):
def doThis(self):
...
def doThat(self):
...
创建类的实例,覆盖类名:
x = x()
定义公开功能的符号:
doThis = x.doThis
doThat = x.doThat
删除实例本身:
del x
现在你有一个只暴露公共功能的模块。
答案 4 :(得分:8)
约定在内部类,函数和变量之前加上“_”。
答案 5 :(得分:4)
要解决设计约定的问题,正如Christopher所说,Python中确实没有“私有”这样的东西。对于那些来自C / C ++背景的人来说,这听起来可能会扭曲(就像我一段时间之前),但最终,你可能会意识到以下约定足够了。
看到前面有下划线的东西应该是一个足够好的提示,不要直接使用它。如果你担心混乱的help(MyClass)
输出(这是每个人在搜索如何使用类时所看到的),那么下面不包含强调的属性/类,所以你最终只能拥有你的“公共“界面描述。
另外,公开所有内容都有自己的特权,例如,你可以从外部对任何东西进行单元测试(你不能用C / C ++私有结构做真的)。
答案 6 :(得分:2)
使用两个下划线为“私有”标识符的名称添加前缀。对于模块中的类,使用单个前导下划线,并且不会使用“from module import *”导入它们。
class _MyInternalClass:
def __my_private_method:
pass
(在Python中没有真正的“私有”这样的东西。例如,Python只会自动将具有双下划线的类成员的名称变为__clssname_mymember
。所以,如果你知道错误的名字你就是无论如何都可以使用“私人”实体。See here.当然,如果你愿意,你可以选择手动导入“内部”类。