zoukankan      html  css  js  c++  java
  • Python----面向对象---封装之如何实现属性的隐藏

    一、引子

    从封装本身的意思去理解,封装就好像是拿来一个麻袋,把小猫,小狗,小王八等一起装进麻袋,然后把麻袋封上口子。

    照这种逻辑看,封装=‘隐藏’,这种理解是相当片面的

    二、如何实现属性的隐藏

    1、在python中用双下划线开头的方式将属性隐藏起来,示例代码如下:

     1 class A:
     2     __x = 1
     3 
     4     def __init__(self, name):
     5         self.name = name
     6 
     7     def __foo(self):
     8         print('run foo')
     9 
    10 print(A.__x)
    11 
    12 结果为:
    13 
    14 Traceback (most recent call last):
    15   File "C:/Users/xudachen/PycharmProjects/Python全栈开发/第三模块/面向对象/17 封装之如何实现属性的隐藏.py", line 12, in <module>
    16     print(A.__x)
    17 AttributeError: type object 'A' has no attribute '__x'

    不仅类A无法访问,A的实例化对象也无法访问

    1 a = A('tel')
    2 print(a.__x)
    3 
    4 结果为:
    5 
    6 Traceback (most recent call last):
    7   File "C:/Users/xudachen/PycharmProjects/Python全栈开发/第三模块/面向对象/17 封装之如何实现属性的隐藏.py", line 16, in <module>
    8     print(a.__x)
    9 AttributeError: 'A' object has no attribute '__x'

    查看A的名称空间:

    print(A.__dict__)
    
    结果为:
    
    {'__module__': '__main__', '_A__x': 1, '__init__': <function A.__init__ at 0x000001B835A03510>, '_A__foo': <function A.__foo at 0x000001B837A9C620>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}

    查看对象a的名称空间

    print(a.__dict__)
    
    结果为:
    
    {'_A__name': 'tel'}

    可以看出,当在属性名前添加__后,发生了变形,这种变形规则是_类名__属性名,

    这种变形的特点是:

    1、在类外部无法直接obj.__AttrName

    2、在类内部是可以直接使用:obj.__AttrName的

    示例代码如下:

     1 class A:
     2     __x = 1
     3 
     4     def __init__(self, name):
     5         self.__name = name
     6 
     7     def __foo(self):
     8         print('run foo')
     9 
    10     def bar(self):
    11         self.__foo()
    12         print('from bar')
    13 
    14 a = A('tel')
    15 a.bar()
    16 
    17 结果为:
    18 
    19 run foo
    20 from bar
    这种操作并不是严格意义上的限制外部访问,仅仅只是一种语法意义上的变形
    3、子类无法覆盖父类__开头的属性
    实例代码如下:
    1 class Foo:
    2     def __func(self):  # _Foo__func
    3         print('from foo')
    4 
    5 
    6 class Bar(Foo):
    7     def __func(self):  # _Bar__func
    8         print('from bar')

    表面上看函数名一样,但是定义阶段就发生了变化,所以子类与父类的函数是不一样的,所以说无法覆盖

    三、隐藏属性的变形是发生在类定义阶段,类定义代码之外是不会发生变形的,实例代码如下:

     1 class B:
     2     __x = 1
     3 
     4     def __init__(self, name):
     5         self.__name = name
     6 
     7 # print(B._B__x)
     8 
     9 B.__y = 2
    10 print(B.__dict__)
    11 
    12 结果为:
    13 
    14 {'__module__': '__main__', '_B__x': 1, '__init__': <function B.__init__ at 0x00000212E0CF3510>, '__dict__': <attribute '__dict__' of 'B' objects>, '__weakref__': <attribute '__weakref__' of 'B' objects>, '__doc__': None, '__y': 2}

    __x 在类定义内部,所以发生了变形,__y 在类定义外部,所以并未发生变形

    对于对象来说也是如此,例如:

    1 b = B('alex')
    2 print(b.__dict__)
    3 b.__age = 18
    4 print(b.__dict__)
    5 
    6 结果为:
    7 
    8 {'_B__name': 'alex'}
    9 {'_B__name': 'alex', '__age': 18}

    四、为类内部的函数属性加上__,可以强制执行类内部的函数

    例如:

     1 class A:
     2     def __foo(self):  # _A__foo
     3         print('A.foo')
     4 
     5     def bar(self):
     6         print('A.bar')
     7         self.__foo()  # self._A__foo()
     8 
     9 class B(A):
    10     def __foo(self):  # _b__foo
    11         print('B.foo')
    12 
    13 b = B()
    14 b.bar()
    15 
    16 结果为
    17 
    18 A.bar
    19 A.foo
     
  • 相关阅读:
    springboot、监听器
    springboot、拦截器
    Thymeleaf模板引擎
    springboot-banner.txt
    springboot,swagger2
    springboot 热部署
    判断是否为微信环境下打开的网页
    后台接收json数据
    ios 面试题
    iOS 适配问题
  • 原文地址:https://www.cnblogs.com/xudachen/p/8609678.html
Copyright © 2011-2022 走看看