魔法方法、属性和迭代器
准备工作
- 元类: 元类是其他类(或类型)的类
构造方法
-
一个构造方法与其他普通方法的不同之处在于: 当一个对象被创建后,会立即调用构造方法。
-
在python中创建一个构造方法很容易。只需要使用
__init__
函数即可:
class FooBar: def __init__(self): self.somevar = 42 f = FooBar() print f.somevar __metaclass__ = type class FooBar(): def __init__(self, value = 42): self.somevar = value f = FooBar('This is a constructor argument') print f.somevar
-
在python所有的魔法方法中,
__init__
是使用最多的一个。
重写一般方法和特殊的构造方法
- 每个类都可能拥有一个或多个超类(或基类),它们从超类那里继承行为方式。
- B继承A,如果一个方法在B类的一个实例中被调用(一个属性被访问),但在B类中没有找到该方法,那么就会去它的超类A里面找。
- 在子类中增加功能的最基本方法就是增加方法。但是也可以重写一些超类的方法来自定义继承的行为。
- 大多数子类不仅要拥有自己的初始化代码,还要拥有超类的初始化代码。
-
虽然重写机制对于所有方法来说都是一样的,但是当处理构造方法比重写普通方法时,更可能遇到特别的问题: 如果一个类的构造方法被重写,那么就需要调用超类的构造方法,否则对象可能不会被正确的初始化。
__metaclass__ = type class Bird: def __init__(self): self.hungry = True def eat(self): if self.hungry: print 'Aaaah...' self.hungry = False else: print 'No, thanks!' class SongBird(Bird): def __init__(self): self.sound = 'Squawk!' def sing(self): print self.sound b = Bird() b.eat() b.eat() b.eat() sb = SongBird() sb.sing() sb.eat() $./test.py Aaaah... No, thanks! No, thanks! Squawk! Traceback (most recent call last): File "./test.py", line 31, in <module> sb.eat() File "./test.py", line 12, in eat if self.hungry: AttributeError: 'SongBird' object has no attribute 'hungry'
调用未绑定的超类构造方法
- 在调用一个实例的方法时,该方法的self参数会被自动绑定到实例上,这称为绑定方法。
-
但如果直接调用类的方法(如
__init__
),那么就会没有实例会被绑定。这样就可以自由的提供需要的self参数,这样的方法称为未绑定方法。
__metaclass = type class Bird: def __init__(self): self.hungry = True def eat(self): if self.hungry: print 'Aaaaah...' 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 b = Bird() b.eat() b.eat() b.eat() sb = SongBird() sb.sing() sb.eat() $./test.py Aaaaah... No, thanks! No, thanks! Squawk! Aaaaah...