Python魔法方法学习笔记一
-
更多分享:http://www.catbro.cn
-
在Python中,有的名称会在前面和后面加上两个下划线,这种写法其实有着特殊的含义。一般不要在自己的程序中使用这种名字
-
在Python中由这些前后带下划线的名字组成的集合所包含的方法成为魔法方法。
-
如果你的对象实现了这些方法中的某一个,那么这个方法会在特殊情况下被Python调用,几乎没有直接调用它的必要
一、构造方法 init()
-
构造方法实例
class ClassA: def __init__(self): print('this is ClassA init method');
-
调用代码:a = ClassA();
-
输出: this is ClassA init method
-
当然,我们的构造函数也是可以带参数的哦
class ClassA: def __init__(self,value1 = ""): print('this is ClassA init method'); print('value1 is %s'%value1);
-
调用代码:a = ClassA(“hello”);
-
输出:
this is ClassA init method value1 is hello
二、重写一般方法
-
每个类都可以有多个超类,如果你调用了一个B类的方法,而B类中并不存在该方法,但是B类是继承A类的,那么就会去A类中查找是否存在该方法
class ClassA: def __init__(self): print('this is ClassA init method'); def say(self): print('I am ClassA'); class ClassB(ClassA): def __init__(self): print('this is ClassB init method'); pass;
-
调用代码:
a = ClassA(); a.say() b = ClassB(); b.say();
-
输出如下:
this is ClassA init method I am ClassA this is ClassB init method I am ClassA
-
可以看到,类B没有定义say方法,其调用的是父类ClassA的say方法。
-
当然,ClassB 可以重写ClassA的say方法
class ClassA: def __init__(self): print('this is ClassA init method'); def say(self): print('I am ClassA'); class ClassB(ClassA): def __init__(self): print('this is ClassB init method'); def say(self): print('I am ClassB');
-
调用代码如下:
a = ClassA(); a.say() b = ClassB(); b.say();
-
输出如下:
this is ClassA init method I am ClassA this is ClassB init method I am ClassB
三、重写构造方法
-
从上面的例子我们可以看到,ClassB继承ClassA,ClassB也有自己的构造函数,但是其并没有调用ClassA的构造函数。这样子会造成什么问题呢?
class ClassA: def __init__(self): self.name = "ClassA"; print('this is ClassA init method'); def say(self): print('I am %s'% self.name); def getName(self): return self.name; class ClassB(ClassA): def __init__(self): print('this is ClassB init method'); def say(self): print('I am ClassB');
-
调用代码如下:
a = ClassA(); a.say() print(a.getName()) b = ClassB(); b.say(); print(b.getName())
-
输出如下:
this is ClassA init method I am ClassA ClassA this is ClassB init method I am ClassB return self.name; AttributeError: 'ClassB' object has no attribute 'name'
-
可以看到,由于ClassB没有调用ClassA的构造函数,到时name属性没有创建。
通过未绑定形式进行调用(python2和python3适用)
-
绑定:在调用一个实例的方法时,该方法的self参数会被自动绑定到实例上。
-
那么我们如果调用未绑定的方法呢?通过类来直接调用方法其实就可以实现了,因为我们的类并未被实例化,也就不存在self,但是我们在调用类方法时,传入当前实例的self,也就可以实现我们的目的了。如在ClassB的构造函数中调用ClassA的构造方法,传入ClassB实例的self。
class ClassA: def __init__(self): print(type(self)) self.name = "ClassA"; print('this is ClassA init method'); def say(self): print('I am %s'% self.name); def getName(self): return self.name; class ClassB(ClassA): def __init__(self): ClassA.__init__(self); print('this is ClassB init method'); def say(self): print('I am ClassB');
-
调用代码如下:
a = ClassA(); a.say() print(a.getName()) b = ClassB(); b.say(); print(b.getName())
-
输出如下(在ClassA的构造函数中输出当前self是什么类型):
<class '__main__.ClassA'> this is ClassA init method I am ClassA ClassA <class '__main__.ClassB'> this is ClassA init method this is ClassB init method I am ClassB ClassA
使用supper函数
-
示例代码如下:
class ClassA: def __init__(self): print(type(self)) self.name = "ClassA"; print('this is ClassA init method'); def say(self): print('I am %s'% self.name); def getName(self): return self.name; class ClassB(ClassA): def __init__(self): super(ClassB,self).__init__(); print('this is ClassB init method'); def say(self): print('I am ClassB');
-
调用代码如下:
a = ClassA(); a.say() print(a.getName()) b = ClassB(); b.say(); print(b.getName())
-
输出如下:
<class '__main__.ClassA'> this is ClassA init method I am ClassA ClassA <class '__main__.ClassB'> this is ClassA init method this is ClassB init method I am ClassB ClassA
-
可以看到,两种实现的效果是一样的。