Python中的“私有”(实现)类

时间:2009-02-15 15:29:40

标签: python access-modifiers

我正在编写一个由两部分组成的小型Python模块:

  • 定义公共接口的一些函数,
  • 上述函数使用的实现类,但在模块外部没有意义。

首先,我决定通过使用它在函数内部定义它来“隐藏”这个实现类,但这会妨碍可读性,如果多个函数重用同一个类,则不能使用它。

那么,除了评论和文档字符串之外,还有一种机制可以将类标记为“私有”或“内部”吗?我知道下划线机制,但据我所知它只适用于变量,函数和方法名称。

7 个答案:

答案 0 :(得分:143)

使用单个下划线前缀:

class _Internal:
    ...

这是'内部'符号的官方Python约定; “from module import *”不会导入以下划线为前缀的对象。

修改:参考single underscore convention

答案 1 :(得分:58)

简而言之:

  1. 您无法强制执行隐私。 Python中没有私有类/方法/函数。至少,不像其他语言那样严格的隐私,例如Java。

  2. 您只能表明/建议隐私。这符合一项惯例。将类/函数/方法标记为私有的python约定是以_(下划线)为前缀。例如,def _myfunc()class _MyClass:。您还可以通过使用两个下划线(例如:__foo)为方法添加前缀来创建伪隐私。您无法直接访问该方法,但您仍然可以使用classname通过特殊前缀来调用它(例如:_classname__foo)。因此,您可以做的最好的事情是表明/建议隐私,而不是强制执行。

  3. 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.当然,如果你愿意,你可以选择手动导入“内部”类。