【发布时间】:2016-12-11 13:45:09
【问题描述】:
我正在阅读我们如何确保 python 中的数据封装。其中一篇博客说 “数据封装意味着,我们应该只能通过 getter 和 setter 访问私有属性”
考虑blog中的以下sn-ps:
class Robot:
def __init__(self, name=None, build_year=None):
self.name = name
self.build_year = build_year
现在,如果我创建类的对象如下:
obj1=Robot()
obj1.name('Robo1")
obj1.build_year("1978")
目前,我可以直接访问属性,因为我已经将它们定义为 public(没有 __notation)
现在为了确保数据封装,我需要将属性定义为私有
使用__ 表示法并通过getter 和setter 访问私有属性。
所以新的类定义如下:
class Robot:
def __init__(self, name=None, build_year=2000):
self.__name = name
self.__build_year = build_year
def set_name(self, name):
self.__name = name
def get_name(self):
return self.__name
def set_build_year(self, by):
self.__build_year = by
def get_build_year(self):
return self.__build_year
现在我将类实例化如下:
x = Robot("Marvin", 1979)
x.set_build_year(1993)
这样,我实现了数据封装,因为私有数据成员不再被直接访问,只能通过类方法访问。
Q1:我们为什么要这样做?我们在保护谁的代码?谁是外部世界?任何拥有源代码的人都可以根据自己的要求对其进行调整,那么我们为什么要添加额外的方法(get/set)来修改/调整属性?
Q2:上面的例子算data encapsulation吗?
【问题讨论】:
-
在 Python 中,您始终可以绕过
setters和getters获取数据。在大多数其他实词计算机语言实现中也是如此,只是不像在 Python 中那么容易,从而给人一种虚假的安全感。 -
请注意,在链接的文章中,在“公共-保护-和私有属性”部分的末尾,它说:“至少有两个很好的理由反对这种方法。首先并非每个私有属性都需要从外部访问。其次,我们将通过这种方式创建非 Python 代码,您将很快了解。
-
通常的 Python 理念是“我们在这里都是成年人”,所以我们通常不会绕过隐藏属性然后添加额外的代码来通过简单的 getter 和 setter 方法访问它们。 OTOH,Python 的描述符机制允许您在确实需要它们时拥有 getter 和 setter(如 chepner 的回答所示),并且这些 getter 和 setter 对您的代码调用者来说就像简单的属性访问一样,因此您可以两全其美。