问题:Python中的“私有”(实现)类
我正在编写一个由两部分组成的小型Python模块:
- 一些定义公共接口的功能,
- 上述函数使用的实现类,但在模块外部没有意义。
首先,我决定通过在使用它的函数内部定义该实现类来“隐藏”该实现类,但这会影响可读性,并且如果多个函数重用同一类,则无法使用该实现类。
因此,除了注释和文档字符串外,是否存在将类标记为“私有”或“内部”的机制?我知道下划线机制,但据我了解,它仅适用于变量,函数和方法名称。
回答 0
回答 1
简而言之:
您不能强制执行隐私。Python中没有私有类/方法/函数。至少,不像其他语言(例如Java)那样严格的隐私保护。
您只能指示/建议隐私。这遵循惯例。将类/函数/方法标记为私有的python约定是在其前加上_(下划线)。例如,
def _myfunc()
或class _MyClass:
。您还可以通过在方法前加上两个下划线(例如:)来创建伪隐私__foo
。您不能直接访问该方法,但仍可以使用类名通过特殊前缀来调用它(例如:)_classname__foo
。因此,您能做的最好的事情就是表明/建议隐私,而不是强制执行。
在这方面,Python就像perl。用Perl的书来解释关于隐私的著名观点,其哲学是您应该离开客厅是因为没有邀请您,而不是因为它是由a弹枪保护的。
想要查询更多的信息:
- 私有变量 Python文档
- 为什么Python的“私有”方法实际上不是私有的? StackOverflow问题70528
回答 2
定义__all__
,要导出的名称列表(请参阅文档)。
__all__ = ['public_class'] # don't add here the 'implementation_class'
回答 3
我有时使用的模式是这样的:
定义一个类:
class x(object):
def doThis(self):
...
def doThat(self):
...
创建类的实例,覆盖类名称:
x = x()
定义公开功能的符号:
doThis = x.doThis
doThat = x.doThat
删除实例本身:
del x
现在,您有了一个仅公开您的公共功能的模块。
回答 4
约定在内部类,函数和变量之前加“ _”。
回答 5
正如克里斯托弗所说,为了解决设计约定的问题,在Python中确实没有“私有”之类的东西。对于来自C / C ++背景的人来说,这听起来可能有点扭曲(就像我前阵子一样),但是最终,您可能会意识到遵循约定已经足够了。
看到前面有下划线的东西应该足够好,不要直接使用它。如果您担心混乱的help(MyClass)
输出(这是每个人在搜索如何使用类时都会看到的内容),那么此处不包括强调的属性/类,因此最终只能描述“公共”接口。
另外,公开的一切都有其令人敬畏的特权,例如,您可以从外部对几乎所有内容进行单元测试(使用C / C ++私有结构实际上无法做到)。
回答 6
使用两个下划线为“专用”标识符的名称添加前缀。对于模块中的类,请使用单个下划线,并且不会使用“ from module import *”来导入它们。
class _MyInternalClass:
def __my_private_method:
pass
(在Python中没有真正的“私有”之类的东西。例如,Python只是自动将带有双下划线的类成员的名称修改为__clssname_mymember
。因此,实际上,如果您知道名称不正确,则无论如何都可以使用“私有”实体。看到这里。当然,你可以选择手动输入“内部”类,如果你想)。