面向对象编程的一个关键部分是封装,它涉及将相关的变量和函数打包到一个简单易用的对象中 - 一个类的实例。

一个相关的概念是数据隐藏,它指出一个类的实现细节应该被隐藏,并且为那些想要使用这个类的用户提供一个干净的标准接口。

在其他编程语言中,这通常使用私有方法和属性来完成,这些私有方法和属性阻止对类中某些方法和属性被外部访问。

Python 略有不同。没有对任何一个阶级的部分进行任意的限制。因此,没有办法强制一个方法或属性是严格私密的。

但是,有些方法可以阻止人们访问某个类的某些部分。
弱的私有方法和属性在开头只有一个下划线。

这表示它们是私有的,不应该被外部代码使用。但是,它大多只是一个约定,并不会阻止外部代码访问它们。

它唯一的实际效果是 from 模块名 import * 不会导入以单个下划线开头的变量。

例如:

class Queue:
  def __init__(self, contents):
    self._hiddenlist = list(contents)

  def push(self, value):
    self._hiddenlist.insert(0, value)

  def pop(self):
    return self._hiddenlist.pop(-1)

  def __repr__(self):
    return "Queue({})".format(self._hiddenlist)

queue = Queue([1, 2, 3])
print(queue)
queue.push(0)
print(queue)
queue.pop()
print(queue)
print(queue._hiddenlist)
======
结果:
Queue([1, 2, 3])
Queue([0, 1, 2, 3])
Queue([0, 1, 2])
[0, 1, 2]

在上面的代码中,_hiddenlist 属性被标记为私有的,但仍然可以在外部代码中访问。
repr 魔术方法用于实例的字符串表示。

强私有方法和属性在名称的开始处有一个双下划线。这导致他们的名字错位,这意味着他们不能从类外访问。

这样做的目的不是确保它们保持私有,而是为了避免错误,如果存在具有相同名称的方法或属性的子类时。

名称 错位 方法仍然可以在外部访问,但是以不同的名称访问。 Spam 类的 __private 方法可以通过 _Spam__private 方法外部访问。

例如:

class Spam:
  __egg = 7
  def print_egg(self):
    print(self.__egg)

s = Spam()
s.print_egg()
print(s._Spam__egg)
print(s.__egg)
======
结果:
7
7
AttributeError: 'Spam' object has no attribute '__egg'

基本上,Python 通过内部更改名称来包含类名来保护这些成员。

最后修改:2022 年 12 月 05 日
如果觉得我的文章对你有用,请随意赞赏