在python中,有的名称会在前面和后面都加上两个下划线,由这些名字组成的集合所包含的方法称为魔法方法,这些方法会在特殊的情况下被Python调用。
魔法方法:
1. 构造方法 __init__
当一个对象被创建后,会立即调用构造方法。在Python所有的魔法方法中,__init__是使用最多的一个。
子类继承父类,如果子类重写了__init__方法,需要调用父类的构造方法来确保进行基本的初始化,否则调用父类的一些方法会报错,有两种方法能调用父类的构造方法:
1) 调用未绑定的超类构造方法
这属于遗留问题,很多遗留代码还是会使用到该方法,仅用于了解,使用super函数的会更简洁明了。
例子:
父类:
class Bird:
def __init__(self):
self.hungry = True
def eat(self):
if self.hungry:
print("eating...")
self.hungry = False
else:
print("No, thanks!")
子类:
class SongBird(Bird):
def __init__(self):
Bird.__init__(self)
self.sound = 'Squawk'
def sing(self):
print(self.sound)
子类中Bird.__init__(self)就实现了调用超类的构造方法,在调用一个实例的方法时,该方法的self参数会被自动绑定到实例上(这被称为绑定方法)。如果写为Bird.__init__,就没有实例被绑定,这样的方法称为未绑定方法。通过将当前的实例作为self参数提供给未绑定方法,子类就能够使用其父类构造方法的所有实现。
2)使用super函数
super函数只能在新式类中使用
class SongBird(Bird):
def __init__(self):
super(SongBird, self).__init__()
self.sound = 'Squawk'
def sing(self):
print(self.sound)
将当前类和对象作为super函数的参数,然后调用父类的__init__方法。super(SongBird, self).__init__中__init__方法以一个普通的绑定方法被调用。这表示也可以通过super调用父类的其他方法,比如super(SongBird, self).eat()
2. 析构方法 __del__
析构方法在对象就要被垃圾回收之前调用。
3. __len__()
该方法返回集合中所含项目的数量,对于序列来说返回的是元素个数,对于映射来说返回的是key-value对的数量。
代码参考:基本的序列和映射规则
4. __getitem__(self.key)
该方法返回与所给键对应的值。对于序列来说,key为坐标索引;对于映射来说,key可以为任何种类的键。
代码参考:基本的序列和映射规则
5. __setitem__(self.key, value)
该方法可以按一定的方式存储和key相关的value,设置完之后可以使用__getitem__获取。该方法只能为可以修改的对象定义这个方法。
代码参考:基本的序列和映射规则
6. __delitem__(self.key)
该方法在对一部分对象使用del语句时被调用,同时必须删除和键相关的键。这个方法也是为可修改的对象定义的。
代码参考:基本的序列和映射规则
7. __getattribute__(self, name)
当特性name被访问时自动被调用。
8. __getattr__(self, name)
当特性name被访问且对象没有相应的特性时被自动调用。
代码参考:拦截对象属性
9. __setattr__(self, name, value)
当给特性name赋值时会被自动调用。
代码参考:拦截对象属性
10. __iter__
一个实现了__iter__方法的对象是可迭代的。
该方法会返回一个迭代器,所谓的迭代器就是具有__next__方法的对象。在调用__next__方法时,迭代器会返回它的下一个值。如果__next__方法被调用,但迭代器没有值可以返回,就会引发一个StopIteration异常。
代码参考:迭代器
11. __next__
一个实现了__next__方法的对象是迭代器。
代码参考:迭代器