如何在Python中编写模块私有/保护方法?

4 投票
1 回答
7790 浏览
提问于 2025-04-18 03:14

我明白在写 Python 模块时,想要定义私有或受保护的函数可以使用

def _func():
    ...

但是我有一个对象层次结构,里面有一些特别的重写。我还想隐藏内部实现(因为这些实现不打算让外部使用,这样我可以在不破坏代码的情况下改进它,虽然我觉得除了我自己,没人会用到它)。如果我使用

class Paragraph(Tag):
    def _method(self):
        ...

并尝试从一个子类 Tag 中调用 _method,IntelliJ IDEA(可能还有 pylint 或其他检查工具)会给我发出警告。有没有办法解决这个问题呢?

我的使用场景是创建一组 markdown 标签对象,以生成一个类似“树”的结构,这个结构可以转换成正确的 markdown 字符串。每个标签都会重写一个受保护的方法来转换自己和它包含的标签,有些标签还会重写一个方法来检查子标签是否有效(例如,不允许嵌套加粗)。只有最顶层的标签上下文有一个公共方法来转换整个树。

编辑:

IntelliJ IDEA 警告:

访问类的受保护成员 _method

1 个回答

8

为了更清楚地说明:

  • 如果一个名字前面有一个下划线,它是“受保护的”。
  • 如果一个名字前面有两个下划线,但后面没有两个下划线,它是“私有的”。

“受保护的”只是一个约定,但语法检查工具会提醒你在类的层级外访问这些内容。

“私有的”是通过名字改写来实现的,这样这个元素只能在定义它的类内部使用。两个下划线会被替换成 _<类名>__。不过,有一些方法可以绕过这个限制……

那么,你遇到的警告是什么呢?在下面的例子中,pylint 不会警告我在 Test 类中使用 _func,但在最后一行我确实收到了一个警告(W0212)。你是不是忘了在基类中定义这个受保护的函数?

class Test(object):
  ''' . '''
  def _func(self):
    ''' . '''
    raise NotImplementedError()
  def fun(self):
    ''' . '''
    self._func()

class Demo(Test):
  ''' . '''
  def _func(self):
    ''' . '''
    print 'Hi'

t = Demo()
t._func()

撰写回答