python面向对象编程(3)|方法和访问权限
今天我们来学习python面向对象编程的三种方法和访问权限。
方法
上次我们已经说过,python面向对象编程一共有三种方法,分别是实例方法,类方法和静态方法。实例方法在前面已经说过,本次主要着重介绍类方法和静态方法。
三种方法的表示形式
![](https://img.haomeiwen.com/i12048719/55e5f23587b1bdbd.jpg)
可以看到,实例化对象可以调用三种方法,而类只能调用类方法和静态方法;实例方法必须传入self参数,类方法必须传入cls参数(当然,你也可以使用其它参数,但是不推荐),而静态方法没有必须要传入的参数。至于@classmethod和@staticmethod,其实是装饰器,先暂时理解为类方法和静态方法的声明吧。
另外需要注意的是,由于类方法中没有传入self,所以不能使用实例属性,而静态方法self和cls都没有传入,所以不能使用类属性和实例属性。
三种方法的调用
![](https://img.haomeiwen.com/i12048719/928036d4ac076a11.jpg)
可以看到,无论是实例方法还是类方法,都不用手动传入self和cls参数。
访问权限
学过Java的舍友就知道,在Java中,可以通过private,public等关键字来控制访问权限,但是在python中是没有这些关键字的,取而代之的是单下划线__和双下划线__ __。
为了演示各种访问权限,我先来定义两个类,这里的Son类继承了Father类,继承我们还没有学,这里先理解为Son类继承了Father类的一些方法和属性。
![](https://img.haomeiwen.com/i12048719/e54a36cd69f21e67.jpg)
我们的验证流程是这样的,先验证公有属性(也就是不加单下划线或双下划线),然后验证半私有属性(加单下划线),最后验证私有属性的访问权限。
公有属性
类内部访问
![](https://img.haomeiwen.com/i12048719/7f7dea451d420e9d.jpg)
类内部可以访问
子类内部访问
![](https://img.haomeiwen.com/i12048719/163cb09730199ce8.jpg)
子类内部也可以访问
同模块其它位置访问
![](https://img.haomeiwen.com/i12048719/4f58e2fc1a07f46f.jpg)
同样,同模块其它位置也可以访问。
跨模块访问
为了验证跨模块访问,我先在属性.py这个模块定义变量a,然后赋值为10,最后在方法.py这个模块访问a,看看能不能成功访问。
![](https://img.haomeiwen.com/i12048719/8f858d0523ef40d4.jpg)
![](https://img.haomeiwen.com/i12048719/dd4150b6c515c18d.jpg)
可以看到,无论是用第一种方法还是用第二种方法导入都可以成功访问。
总结:公有属性在类内部、子类内部、同模块其它位置以及其它模块都可以访问。
半私有属性
半私有属性只要在属性面前加上单下划线即可,我们采用同验证公有属性的访问权限相同的方式来验证半私有属性的访问权限。
类内部访问
![](https://img.haomeiwen.com/i12048719/32bf819fc71684cc.jpg)
类内部可以访问半私有属性
子类内部访问
![](https://img.haomeiwen.com/i12048719/f9d3296757c4dc0b.jpg)
子类内部也可以访问半私有属性。
同模块其它位置访问
![](https://img.haomeiwen.com/i12048719/e347fae96680471b.jpg)
同样,同模块其它位置也可以访问半私有属性。
跨模块访问
同样,为了验证跨模块访问,我先在属性.py这个模块定义变量_a,然后赋值为10,最后在方法.py这个模块访问_a,看看能不能成功访问。
import ······方式
![](https://img.haomeiwen.com/i12048719/7ca9a93ff3891007.jpg)
from ···· import * 方式
![](https://img.haomeiwen.com/i12048719/52525d1159ff67be.jpg)
可以看到,第二种导入方式不可以访问半私有属性。
总结:公有属性在类内部、子类内部、同模块其它位置都可以访问,在跨模块中是否可以访问取决于导入方式,import ······导入方式可以访问半私有属性,from ···· import * 导入方式则不可以访问。另外虽然同模块其它位置和跨模块可以访问半私有属性,但是不建议访问。
私有属性
私有属性只要在属性面前加上双下划线即可,我们采用同验证公有属性和半私有属性的访问权限相同的方式来验证私有属性的访问权限。
类内部访问
![](https://img.haomeiwen.com/i12048719/56bdd554f7429726.jpg)
类内部可以访问私有属性。
子类内部访问
![](https://img.haomeiwen.com/i12048719/ef4f0b376ea2bf93.jpg)
报错了,子类内部不可以访问私有属性,注意看报错原因,Son类没有_Son__age属性,额···,我们也没有给Father类和Son类设置了_Son__age属性啊,报这个错是什么鬼?别急,我们先来看看Father类有哪些属性。
![](https://img.haomeiwen.com/i12048719/7132d826091cbe05.jpg)
其它乱七八糟的东西先别看,注意红框的位置,我们明明设置的是__age属性,怎么跑出来一个_Father__age属性?
我们的公有属性和半私有属性都是设置了什么属性内部就储存什么属性,不信看下面。
![](https://img.haomeiwen.com/i12048719/0aba6c5ee2a40552.jpg)
![](https://img.haomeiwen.com/i12048719/db3f701da8b3ebc1.jpg)
所以说,我们设置的私有属性只是一个假象,它在内存中真正的形式是''_类名__属性'',这就是名字的重整,提高安全性。
同模块其它位置访问
![](https://img.haomeiwen.com/i12048719/21532be20b48690c.jpg)
依然报错,剩下的三个也是一样的报错信息,这里就不再进行验证了。所以说,同模块其它位置也不可以访问私有属性。
跨模块访问
![](https://img.haomeiwen.com/i12048719/da7036fe47e8566c.jpg)
![](https://img.haomeiwen.com/i12048719/789b906f95b3136d.jpg)
可以看出,无论哪一种导入方式,跨模块都不可以访问私有属性。
总结:私有属性除了类内部可以访问之外,其它地方都不可以访问。
最后,用一张图来个大总结吧
![](https://img.haomeiwen.com/i12048719/cb5c0dabf5f2539c.jpg)
本期就到这里,谢谢捧场!
![](https://img.haomeiwen.com/i12048719/9d4c7567961234f1.jpg)