Python类封装

Python类封装教程

封装是面向对象的三大特征之一,它指的是将 对象 的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该 所提供的 方法 来实现对内部信息的操作和访问。

封装机制保证了类内部数据结构的完整性,因为使用类的用户无法直接看到类中的数据结构,只能使用类允许公开的数据,很好地避免了外部对内部数据的影响,提高了程序的可维护性。

Python类封装的好处

  1. 隐藏类的实现细节
  2. 让使用者只能通过事先预定的方法来访问数据,从而可以在该方法里加入控制逻辑,限制对属性的不合理访问。
  3. 可进行数据检查,从而有利于保证对象信息的完整性。
  4. 便于修改,提高代码的可维护性。

Python类封装的实现

类的封装,其实是需要将对象的 属性 和实现细节隐藏起来,不允许外部直接访问。把方法暴露出来,让方法来控制对这些属性进行安全的访问和操作。因此,实际上封装有两个方面的含义:把该隐藏的隐藏起来,把该暴露的暴露出来。

Python 中,为了实现封装,我们需要将需要隐藏的属性 私有化,即使用双下划线修饰类的属性,即 __

案例

Python类私有方法

使用 __ 修饰类的方法,使类的方法私有化

print("嗨客网(www.haicoder.net)") class Person(object): def __init__(self, name, age): self.name = name self.age = age def info(self): print("Name =", self.name, "Age =", self.age) person = Person("", -18) person.info()

程序运行后,控制台输出如下:

75_python类封装.png

我们定义了一个 Person 类,并且 Person 类有两个属性,分别为 name 和 age,接着,在实例化 Person 类时,我们给 Person 类实例的 name 字段设置为了 “”,age 字段设置了 -18。

这两个字段的值明显是不合理的,但此时我们没法控制这两个不合理的值,因此我们将程序修改如下:

print("嗨客网(www.haicoder.net)") class Person(object): def __init__(self, name, age): if len(name) == 0: self.name = "HaiCoder" else: self.name = name if age < 1: self.age = 1 else: self.age = age def info(self): print("Name =", self.name, "Age =", self.age) person = Person("", -18) person.info()

程序运行后,控制台输出如下:

76_python类封装.png

我们在 构造函数 里面,加了逻辑判断,如果传入的 name 属性是空,那么就将名字设置为 “HaiCoder”,如果 age 属性小于 1,那么就设置为 1,虽然不太合理,但至少避免了数据错。我们再次将程序修改如下:

print("嗨客网(www.haicoder.net)") class Person(object): def __init__(self, name, age): if len(name) == 0: self.name = "HaiCoder" else: self.name = name if age < 1: self.age = 1 else: self.age = age def info(self): print("Name =", self.name, "Age =", self.age) person = Person("", -18) person.info() person.name = "" person.age = -18 person.info()

程序运行后,控制台输出如下:

77_python类封装.png

我们发现,如果我们单独使用赋值的方式,来设置类的属性的值,还是可以设置不合理的值。我们再次将程序修改如下:

print("嗨客网(www.haicoder.net)") class Person(object): def __init__(self, name, age): if len(name) == 0: self.__name = "HaiCoder" else: self.__name = name if age < 1: self.__age = 1 else: self.__age = age def setname(self, val): if len(val) == 0: self.__name = "HaiCoder" else: self.__name = val def getname(self): return self.__name name = property(getname, setname) def setage(self, val): if val < 1: self.__age = 1 else: self.__age = val def getage(self): return self.__age age = property(getage, setage) def info(self): print("Name =", self.__name, "Age =", self.__age) person = Person("", -18) person.info() person.name = "haicoder" person.age = 109 person.info() person.name = "" person.age = -18 person.info()

程序运行后,控制台输出如下:

78_python类封装.png

我们将类的 name 属性和 age 属性设置为了私有属性,同时,使用了 get 和 set 方法为这两个私有属性提供了设置值和访问的方法,在设置值的时候,我们判断了值的合法性,从而保证了数据的安全。

但是,我们发现,构造函数里面的 if 判断 与 set 方法里面的 if判断很类似,代码有点冗余,因此,我们再次将程序修改如下:

print("嗨客网(www.haicoder.net)") class Person(object): def __init__(self, name, age): self.__setname(name) self.__setage(age) def setname(self, val): self.__setname(val) def getname(self): return self.__name name = property(getname, setname) def setage(self, val): if val < 1: self.__age = 1 else: self.__age = val def getage(self): return self.__age age = property(getage, setage) def info(self): print("Name =", self.__name, "Age =", self.__age) def __setname(self, val): if len(val) == 0: self.__name = "HaiCoder" else: self.__name = val def __setage(self, val): if val < 1: self.__age = 1 else: self.__age = val person = Person("", -18) person.info() person.name = "haicoder" person.age = 109 person.info() person.name = "" person.age = -18 person.info()

程序运行后,控制台输出如下:

79_python类封装.png

我们将设置 name 属性和设置 age 属性的代码,抽象出来了,独立成为了一个私有的 __setname 方法和一个私有的 __setage 方法,然后,在构造函数和 set 函数里面,都调用私有的方法,从而避免了代码的冗余。

Python类封装总结

类的封装,其实是需要将对象的属性和实现细节隐藏起来,不允许外部直接访问。把方法暴露出来,让方法来控制对这些属性进行安全的访问和操作。因此,实际上封装有两个方面的含义:把该隐藏的隐藏起来,把该暴露的暴露出来。

在 Python 中,为了实现封装,我们需要将需要隐藏的属性私有化,即使用双下划线修饰类的属性,即 __