美文网首页大数据 爬虫Python AI SqlPython小哥哥
Python面向对象三大特征之封装 !

Python面向对象三大特征之封装 !

作者: 14e61d025165 | 来源:发表于2019-04-12 15:17 被阅读0次

    今天这篇文章,说说封装的概念和使用,封装从字面意思来说就是把东西装起来,然后封好口子,我们想想这样能实现什么效果?外面的人看不见里面的东西,但是里面的人可以看见。这其实就是封装最主要的用意。

    封装的含义和特点

    对外人员访问只需要部模块导入,或者访问接口调用函数,看不到内部实现
    封装的属性在内部可以直接调用
    封装的属性在外部不能直接使用,但是可以通过其他方式,比如预留get接口访问,我们后面再说
    封装的内在含义就是明确内部和外部,把内外分开,提升安全性

    下面我们看代码吧,看看简单的封装是什么样子的

    封装.py

    class package:
    name = 'package1'
    def get(self):
    print('get package')

    封装2.py

    from 封装 import package as pk
    pk.get('xxxx')

    上面可以看到封装2.py导入package,让调用get方法,但是他却不知道get的方法的具体实现,这就是最简单的封装,不然外部看到具体实现的方法和属性

    下面再看看封装还有那些用法,python中还有使用单下划线和双下划线的方法来隐藏属性,设置私有属性,但是看到后面我们会知道这只是一种代码规范的约定,并不能实现真正的属性私有。

    但是我们如果作为代码的调用者,当我们看到变量或者方法是以单下划线和双下划线开头的时候,我们要知道,这是代码作者,不想让我们再外部调用的,是你和代码作者之间的一种约定,当然你不遵守,代码作者也没有办法,下面我们看看案例代码

    class package:
    def init(self,name,age):
    self. _name = name #单下划线私有变量
    self.__age = age #双下划线私有变量
    def get(self):
    print('get package')
    p1 = package('cat',10)
    print(p1.dict) #实例的数据属性
    Python学习群:683380553,有大牛答疑,有资源共享!有想学习python编程的,或是转行,或是大学生,还有工作中想提升自己能力的,正在学习的小伙伴欢迎加入学习。

    结果:

    {'_name': 'cat', '_package__age': 10}

    我们看到内部把原来的私有变量__age 变成了_package__age,只是变了一个名字,让我们在外部没办法调用,我们来试试

    class package:
    def init(self,name,age):
    self. _name = name #单下划线私有变量
    self.__age = age #双下划线私有变量
    def get(self):
    print('get package')
    p1 = package('cat',10)

    print(p1.dict) #实例的数据属性

    print(p1._name) #结果:cat 可以正常调用单下划线的私有变量,所以说这只是一种约定,不是强制的不给调用
    print(p1.__age) #报错 AttributeError: 'package' object has no attribute '__age' 说明外部找不到这个属性

    那下面我们来换下属性的名字试试,根据dict字典里面的名字

    class package:
    def init(self,name,age):
    self. _name = name #单下划线私有变量
    self.__age = age #双下划线私有变量
    def get(self):
    print('get package')
    p1 = package('cat',10)

    print(p1.dict) #实例的数据属性

    print(p1._name) #结果:cat 可以正常调用单下划线的私有变量,所以说这只是一种约定,不是强制的不给调用
    print(p1._package__age) #结果:10 换了名字可以正常访问 所以说这也只是一种约定,不是强制外部不给调用

    那现在我们看看类内部如果想调用,是否需要换掉私有变量的名字

    class package:
    def init(self,name,age):
    self. _name = name #单下划线私有变量
    self.__age = age #双下划线私有变量
    def get(self):
    print(self._name,self.__age) #类内部调用,并且没有换私有变量的名字
    p1 = package('cat',10)
    p1.get() #结果:cat 10

    上面的结果我们可以看到类内部调用私有变量,完全没有什么问题,所以我们说封装的内涵就是隔离内外,把内外分开。

    上面就是封装的大致含义和作用以及用法。下面我们看看封装时候需要注意的点,我们封装是为了保护一些数据不外露,但是如果一些数据我们想隐藏,但是也要给一些人可以访问,那么我们就要注意,不能滥用封装,要留有一些get, set接口给外部用户使用,这些会随着项目的开发进度逐渐显示出来,所以我们要注意不能滥用封装,已经要留有接口

    class package:
    def init(self,name,age):
    self. _name = name #单下划线私有变量
    self.__age = age #双下划线私有变量
    def get(self):
    print(self._name,self.__age) #类内部调用,并且没有换私有变量的名字
    def get_age(self):
    return self.__age
    p1 = package('cat',10)
    print(p1.get_age()) #10,外部想要调用类内部的私有变量,可以留下这样的get方法,作为接口,外部不需要看到内部的具体实现,只需要取到自己想要的数据即可

    python并不会真的阻止你访问私有的属性,模块也遵循这种约定,如果模块名以单下划线开头,那么from module import *时不能被导入,但是你from module import _private_module依然是可以导入的

    其实很多时候你去调用一个模块的功能时会遇到单下划线开头的(socket._socket,sys._home,sys._clear_type_cache),这些都是私有的,原则上是供内部调用的,作为外部的你,一意孤行也是可以用的,只不过不建议这么使用

    python要想与其他编程语言一样,严格控制属性的访问权限,只能借助内置方法如getattr,后面文章会说到

    最后再说下封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者的代码;而外部使用用者只知道一个接口(函数),只要接口(函数)名、参数不变,使用者的代码永远无需改变。这就提供一个良好的合作基础——或者说,只要接口这个基础约定不变,则代码改变不足为虑。

    相关文章

      网友评论

        本文标题:Python面向对象三大特征之封装 !

        本文链接:https://www.haomeiwen.com/subject/tkmcwqtx.html