关于Pyhton3中类相关知识,例如抓狂的self!!!
0 继承/重写/Super
继承
1 | class Parent: |
在这里,Parent
类是父类,Child
类是子类,但是通过定义,继承了父类。所以在后面实例化之后,son
依然可以调用父类的函数。最后的运行结果如下:
重写(Override)
子类除了可以继承父类的函数,也能够对父类函数进行重写
1 | class Parent: |
Super
Super,超类,当既重写了同名的父类函数也在重写时调用了父类函数
1 | class Parent: |
特性(property)
property使得类函数成为一种属性,能够像属性一样直接访问,访问时就默认执行该函数并返回值
但是,和真正的属性还是存在本质区别的,比如此时无法被赋值,只能根据其他属性的变化来更新
为啥要用他呢
将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则
面向对象的封装有三种方式:
【public】
这种其实就是不封装,是对外公开的
【protected】
这种封装方式对外不公开,但对朋友(friend)或者子类(形象的说法是“儿子”,但我不知道为什么大家 不说“女儿”,就像“parent”本来是“父母”的意思,但中文都是叫“父类”)公开
【private】
这种封装对谁都不公开
但是,python并没有在语法上C中的私有/公有/保护(private/public/protect)内建到自己的class机制中,在C++里一般会将所有的所有的数据都设置为私有的,然后提供set和get方法(接口)去设置和获取,在python中通过property方法可以实现
1 | import math |
静态方法(staticmethod)
主要就是可以不实例化类而直接调用函数,但是有点奇怪,好像不用静态方法也可以实现呀,如下图:
有博客提供了一个应用场景,提到需要采用多种不同的方式创建实例时,而我们只有一个init函数,此时就可静态方法
1 | class Date: |
类方法(classmethod)
1 为什么要加Object呢
1.1 Object?
1.2 为啥?
Python2时,都建议在类声明的时候加上object,其实就是继承,使其具有更多的操作对象,而在Python3中,已经默认加载了Object了
Python2
Python3
1.3 经典类/新式类
其实还有个小问题,就是在Python2中,存在多重继承时的继承方式寻找问题,如果是不继承object的则是经典类,如果继承了object则为新式类,二者的具体区别如下图所示,而Python3中呢,前文已经提到所有类在定义时都默认继承了object,所以你猜他是啥类?
2 为什么一定要加self
2.1 为什么
self指向的是类的实例,如下图,蓝色框中
像函数一样,Python中的类方法也是一种对象。由于既可以通过实例也可以通过类来访问方法,所以在Python里有两种风格:
未绑定的类方法:没有self
通过类来引用方法返回一个未绑定方法对象。要调用它,你必须显示地提供一个实例作为第一个参数。
绑定的实例方法:有self
通过实例访问方法返回一个绑定的方法对象。Python自动地给方法绑定一个实例,所以我们调用它时不用再传一个实例参数。
两种方法都是对象,它们可以被传递、存入列表等待。两者运行时都需要一个实例作为第一参数,但当通过一个实例调用一个绑定方法时Python自动会提供一个。
而在Python的编译中,如上图蓝色框中所示,t.prt()是会转化为test.prt(t),二者是等价的,所以如果在类函数定义时加入了self参数,相当于绑定了实例
而如果不加self参数,那么只能够通过自己暂时实例化一个类调用,例如下图蓝框中第二种方式,如果是第一种方式,则会显示多给了一个参数,原因是编译的时候默认加入了self参数,所以显示参数多了,如红框中的使用,t4.add(1,2)=test4.add(t4,1,2)
2.2 一定要self?
习惯了C指针的也可以用this
而事实上,啥名都行,他会默认用函数的第一个参数作为self
1 | class Test: |
2.3 是谁的self?
那如果我是继承父类的函数,那么继承函数的self是谁的self呢?
在继承时,是哪个实例的函数,就是谁的self,而非定义时的self
1 | class Parent: |
3 我打(印)我自己
上文提到可以访问类的各个属性,那么如果我直接打印类呢,比如 print(class) 呢?
1 | #__str__定义在类内部,必须返回一个字符串类型, |
引用
Python中新式类 经典类的区别(即类是否继承object)
python基础——特性(property)、静态方法(staticmethod)、类方法(classmethod)、str的用法