Python封装底层实现原理详解(通俗易懂)
事实上,Python 封装特性的实现纯属“投机取巧”,之所以类对象无法直接调用以双下划线开头命名的类属性和类方法,是因为其底层实现时,Python 偷偷改变了它们的名称。
前面章节中,我们定义了一个 CLanguage 类,定义如下:
那么,是不是类似 display() 这种的私有方法,真的没有方法调用吗?如果你深入了解 Python 封装机制的底层实现原理,就可以调用它。
事实上,对于以双下划线开头命名的类属性或类方法,Python 在底层实现时,将它们的名称都偷偷改成了 "_类名__属性(方法)名" 的格式。
就以 CLanguage 类中的 __display() 为例,Python 在底层将其方法名偷偷改成了“_CLanguage__display()”。例如,在 CLanguage 类的基础上,执行如下代码:
不仅如此,那些原本我们认为是私有的类属性(例如 __name 和 __add),其底层的名称也改成了“_类名__属性名”的这种格式。例如:
前面章节中,我们定义了一个 CLanguage 类,定义如下:
class CLanguage : def setname(self, name): if len(name) < 3: raise ValueError('名称长度必须大于3!') self.__name = name def getname(self): return self.__name #为 name 配置 setter 和 getter 方法 name = property(getname, setname) def setadd(self, add): if add.startswith("http://"): self.__add = add else: raise ValueError('地址必须以 http:// 开头') def getadd(self): return self.__add #为 add 配置 setter 和 getter 方法 add = property(getadd, setadd) #定义个私有方法 def __display(self): print(self.__name,self.__add)注意,在这个类中,有一个 __display() 方法,由于其是私有方法,且该类没有提供任何调用该方法的“接口”,因此在目前看来,此方法根本无法在类外部调用。也就是说,如下调用 __display() 方法是不可行的:
clang = CLanguage() #尝试调用私有的 display() 方法 clang.__display()这会导致如下错误:
Traceback (most recent call last):
File "D:\python3.6\1.py", line 33, in <module>
clang.__display()
AttributeError: 'CLanguage' object has no attribute '__display'
那么,是不是类似 display() 这种的私有方法,真的没有方法调用吗?如果你深入了解 Python 封装机制的底层实现原理,就可以调用它。
事实上,对于以双下划线开头命名的类属性或类方法,Python 在底层实现时,将它们的名称都偷偷改成了 "_类名__属性(方法)名" 的格式。
就以 CLanguage 类中的 __display() 为例,Python 在底层将其方法名偷偷改成了“_CLanguage__display()”。例如,在 CLanguage 类的基础上,执行如下代码:
clang = CLanguage() #调用name的setname()方法 clang.name = "新宝库" #调用add的setadd()方法 clang.add = "https://www.xinbaoku.com" #直接调用隐藏的display()方法 clang._CLanguage__display()输出结果为:
新宝库 https://www.xinbaoku.com
不仅如此,那些原本我们认为是私有的类属性(例如 __name 和 __add),其底层的名称也改成了“_类名__属性名”的这种格式。例如:
clang = CLanguage() clang.name = "新宝库" clang.add = "https://www.xinbaoku.com" #直接调用 name 和 add 私有属性 print(clang._CLanguage__name,clang._CLanguage__add)运行结果为:
新宝库 https://www.xinbaoku.com
甚至于,我们还可以通过这种方式修改 clang 对象的私有属性,例如:clang._CLanguage__name = "Python教程" clang._CLanguage__add = "https://www.xinbaoku.com/python" print(clang._CLanguage__name,clang._CLanguage__add)输出结果为:
Python教程 https://www.xinbaoku.com/python
总结
Python 类中所有的属性和方法,都是公有(public)属性,如果希望 Python 底层修改类属性或者类方法的名称,以此将它们隐藏起来,只需将它们的名称前添加双下划线(“__”)即可。所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算