Python面向对象编程第08篇 私有变量
Posted 不剪发的Tony老师
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python面向对象编程第08篇 私有变量相关的知识,希望对你有一定的参考价值。
本篇我们介绍封装(encapsulation)的概念,以及如何在 Python 中利用私有属性实现封装。
封装的概念
面向对象编程包含四个基本的概念:抽象、封装、继承以及多态。封装是指将数据和功能包装在对象中,通过封装可以对外隐藏对象的内部状态。封装因此也被称为信息隐藏。
类就是封装的一个示例,它将数据和方法打包成一个单元。同时类还通过方法提供了属性的访问。
信息隐藏的思想就是如果你有一个外部不可见的属性,你可以控制它的访问,确保对象总是处于有效状态。
下面我们通过一个示例来进一步理解封装的概念。
封装的示例
以下示例定义了一个 Counter 类:
class Counter:
def __init__(self):
self.current = 0
def increment(self):
self.current += 1
def value(self):
return self.current
def reset(self):
self.current = 0
Counter 类拥有一个属性 current,它的默认值为 0。另外 Counter 类包含三个方法:
- increment() 将属性 current 的值加一。
- value() 返回属性 current 的当前值。
- reset() 将属性 current 的值设置为 0。
以下示例创建了一个新的 Counter 类实例,调用三次 increment() 方法,然后打印 counter 变量的当前值:
counter = Counter()
counter.increment()
counter.increment()
counter.increment()
print(counter.value())
输出结果如下:
3
程序工作正常,但是还有一个问题。我们仍然可以从 Counter 类的外部访问 current 属性并修改它的值。例如:
counter = Counter()
counter.increment()
counter.increment()
counter.current = -999
print(counter.value())
输出结果如下:
-999
在以上示例中,我们创建了一个 Counter 类的实例,调用两次 ncrement() 方法,然后将 current 属性的值设置为一个无效的数值 -999。
那么如何阻止代码从 Counter 类的外部修改 current 属性呢?为此我们需要使用私有属性。
私有属性
私有属性只能从类的方法中访问。也就是说,我们无法从类的外部访问私有属性。
不过,Python 没有提供私有属性的功能。也就是说,任何属性都可以从类的外部访问。
按照惯例,我们可以在变量名前加上一个下划线(_)表示私有属性:
_attribute
以上语法表示 _attribute 不应该直接访问,而且将来在实现上可能会有重大变化。
以下示例重新定义了 Counter 类,使用惯例将 current 变量修改为私有属性:
class Counter:
def __init__(self):
self._current = 0
def increment(self):
self._current += 1
def value(self):
return self._current
def reset(self):
self._current = 0
名称改写
如果在属性名前面加上双下划线前缀:
__attribute
Python 会自动将 __attribute 属性名修改为以下名称:
_class__attribute
这种行为被称为名称改写(name mangling)。这样一来,我们就无法从外部访问直接访问 __attribute 属性:
instance.__attribute
不过,我们还是可以通过 _class__attribute 访问变量:
instance._class__attribute
以下示例重新定义了 Counter 类:
class Counter:
def __init__(self):
self.__current = 0
def increment(self):
self.__current += 1
def value(self):
return self.__current
def reset(self):
self.__current = 0
此时,如果我们访问 __current 属性,将会返回一个错误:
counter = Counter()
print(counter.__current)
AttributeError: 'Counter' object has no attribute '__current'
但是我们可以通过 _Counter___current 访问 __current 属性:
counter = Counter()
print(counter._Counter__current)
0
总结
- 封装是将数据和方法打包成一个类,从而隐藏信息和限制外部访问。
- 按照惯例,单下划线前缀的属性被视为私有属性。
- Python 会对双下划线前缀的属性进行名称改写。
以上是关于Python面向对象编程第08篇 私有变量的主要内容,如果未能解决你的问题,请参考以下文章