Python中是如何封装的

python

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

就好比使用计算机,我们只需要使用计算机提供的键盘,就可以达到操作计算机的目的,至于在敲击键盘时计算机内部是如何工作,我们根本不需要知道。

Python 并没有提供类似于其他语言的 private 等修饰符,因此 Python 并不能真正支持隐藏。为了隐藏类中的成员,Python 玩了一个小技巧:只要将 Python 类的成员命名为以双下画线开头的,Python 就会把它们隐藏起来。

例如,如下程序示范了 Python 的封装机制:

class User :

    def __hide(self):

        print('示范隐藏的hide方法')

    def getname(self):

        return self.__name

    def setname(self, name):

        if len(name) < 3 or len(name) > 8:

            raise ValueError('用户名长度必须在3~8之间')

        self.__name = name

    name = property(getname, setname)

    def setage(self, age):

        if age < 18 or age > 70:

            raise ValueError('用户名年龄必须在18在70之间')

        self.__age = age

    def getage(self):

        return self.__age

    age = property(getage, setage)

# 创建User对象

u = User()

# 对name属性赋值,实际上调用setname()方法

u.name = 'fk' # 引发 ValueError: 用户名长度必须在3~8之间

上面程序将 User 的两个实例变量分别命名为 __name 和 __age,这两个实例变量就会被隐藏起来,这样程序就无法直接访问 __name、__age 变量,只能通过 setname()、getname()、setage()、getage() 这些访问器方法进行访问,而 setname()、setage() 会对用户设置的 name、age 进行控制,只有符合条件的 name、age 才允许设置。

上面程序尝试将 User 对象的 name 设为 fk,这个字符串的长度为“2”不符合实际要求,因此运行程序最后一行包含如下错误:

ValueError:用户名长度必须在3-8之间

将最后一行代码注释掉,并在程序尾部添加如下代码:

u.name = 'fkit'

u.age = 25

print(u.name) # fkit

print(u.age) # 25

此时程序对 name、age 所赋的值都符合要求,因此上面两行赋值语句完全可以正常运行。运行上面代码,可以看到如下输出结果:

fkit

25

从该程序可以看出封装的好处,程序可以将 User 对象的实现细节隐藏起来,程序只能通过暴露出来的 setname()、setage() 方法来改变 User 对象的状态,而这两个方法可以添加自己的逻辑控制,这种控制对 User 的修改始终是安全的。上面程序还定义了一个 __hide() 方法,这个方法默认是隐藏的。如果程序尝试执行如下代码:

# 尝试调用隐藏的__hide()方法

u.__hide()

将会提示如下错误:

AttributeError:'User' object has no attribute 'hide'

最后需要说明的是,Python 其实没有真正的隐藏机制,双下画线只是 Python 的一个小技巧,Python 会“偷偷”地改变以双下画线开头的方法名,会在这些方法名前添加单下画线和类名。因此上面的 __hide() 方法其实可以按如下方式调用(通常并不推荐这么干):

# 调用隐藏的__hide()方法

u._User__hide()

运行上面代码,可以看到如下输出结果:

示范隐藏的hide方法

通过上面调用可以看出,Python 并没有实现真正的隐藏。

类似的是,程序也可通过为隐藏的实例变量添加下画线和类名的方式来访问或修改对象的实例变量。例如如下代码:

# 对隐藏的__name属性赋值

u._User__name = 'fk'

# 访问User对象的name属性(实际上访问__name实例变量)

print(u.name)

更多学习内容,请点击Python学习网。

以上是 Python中是如何封装的 的全部内容, 来源链接: utcz.com/z/522656.html

回到顶部