Python 中的“ Private”(实现)类

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

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

起初,我决定通过在使用它的函数中定义它来“隐藏”这个实现类,但是这妨碍了可读性,并且如果多个函数重用同一个类,就不能使用它。

那么,除了注释和文档字符串之外,是否还有一种机制来将类标记为“ private”或“ Internal”?我知道下划线机制,但据我所知,它只适用于变量、函数和方法的名称。

129809 次浏览

约定是在内部类、函数和变量前面加上“ _”。

使用单个下划线前缀:

class _Internal:
...

这是 Python 对“内部”符号的正式约定; “ from module import *”不导入带下划线的前缀对象。

参考 单下划线约定单下划线约定

定义 __all__,即要导出的名称列表(请参阅文件)。

__all__ = ['public_class'] # don't add here the 'implementation_class'

我有时使用的一种模式是这样的:

定义一个类:

class x(object):
def doThis(self):
...
def doThat(self):
...

创建类的实例,覆盖类名:

x = x()

定义公开功能的符号:

doThis = x.doThis
doThat = x.doThat

删除实例本身:

del x

现在您有了一个只公开公共函数的模块。

使用两个下划线作为“私有”标识符名称的前缀。对于模块中的类,使用单个前导下划线,不会使用“ from module import *”导入它们。

class _MyInternalClass:
def __my_private_method:
pass

(在 Python 中没有真正的“私有”这回事。例如,Python 只是自动将带有双下划线的类成员的名称改为 __clssname_mymember。因此,如果您知道错误的名称,无论如何都可以使用“私有”实体。当然,如果你想的话,你也可以选择手动导入“内部”类)。

为了解决设计约定的问题,作为 罗德说,在 Python 中实际上没有“ private”这样的东西。对于那些来自 C/C + + 背景的人(比如我)来说,这听起来可能有些扭曲,但是最终,你可能会意识到遵循惯例已经足够了。

看到前面有一个下划线应该是一个很好的提示,不要直接使用它。如果您担心 help(MyClass)输出混乱(每个人在搜索如何使用类时都会看到这一点) ,那么强调的属性/类就不会包含在其中,因此您最终只会看到“ public”接口的描述。

另外,所有东西都是公共的也有它自己的好处,例如,你可以从外部进行单元测试(这在 C/C + + 私有构造中是做不到的)。

简而言之:

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

  2. 您只能指示/建议隐私 。这符合惯例。将 class/function/method 标记为 private 的 Python 约定是在前面加上 _ (下划线)。例如,def _myfunc()class _MyClass:。还可以通过在方法前面加两个下划线(例如,__foo)来创建伪隐私。您不能直接访问该方法,但是您仍然可以使用类名(例如,_classname__foo)通过一个特殊的前缀调用它。所以你能做的最好的就是暗示/暗示隐私,而不是强制执行。

Python 在这方面就像 Perl。借用 Perl 书中关于隐私的一句著名的话,其哲学是您应该远离起居室,因为您没有受到邀请,而不是因为它有猎枪保护。

了解更多信息: