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
 
原文地址:https://www.cnblogs.com/xudachen/p/8609678.html