使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例的时候,类似 java 等 OO 语言里的构造器。例如:
# -*- coding: utf-8 -*- class Person(object): """Silly Person""" def __init__(self, name, age): self.name = name self.age = age def __str__(self): return '<Person: %s(%s)>' % (self.name, self.age) if __name__ == '__main__': piglei = Person('piglei', 24) print piglei这样便是__init__最普通的用法了。但__init__其实不是实例化一个类的时候第一个被调用 的方法。当使用 Persion(name, age) 这样的表达式来实例化一个类时,最先被调用的方法 其实是 __new__ 方法。
# -*- coding: utf-8 -*- class Person(object): """Silly Person""" def __new__(cls, name, age): print '__new__ called.' return super(Person, cls).__new__(cls, name, age) def __init__(self, name, age): print '__init__ called.' self.name = name self.age = age def __str__(self): return '<Person: %s(%s)>' % (self.name, self.age) if __name__ == '__main__': piglei = Person('piglei', 24) print piglei执行结果:
通过运行这段代码,我们可以看到,__new__方法的调用是发生在__init__之前的。其实当 你实例化一个类的时候,具体的执行逻辑是这样的:
class PositiveInteger(int): def __init__(self, value): super(PositiveInteger, self).__init__(self, abs(value)) i = PositiveInteger(-3) print i但运行后会发现,结果根本不是我们想的那样,我们任然得到了-3。这是因为对于int这种 不可变的对象,我们只有重载它的__new__方法才能起到自定义的作用。
class PositiveInteger(int): def __new__(cls, value): return super(PositiveInteger, cls).__new__(cls, abs(value)) i = PositiveInteger(-3) print i通过重载__new__方法,我们实现了需要的功能。
class Singleton(object): def __new__(cls): # 关键在于这,每一次实例化的时候,我们都只会返回这同一个instance对象 if not hasattr(cls, 'instance'): cls.instance = super(Singleton, cls).__new__(cls) return cls.instance obj1 = Singleton() obj2 = Singleton() obj1.attr1 = 'value1' print obj1.attr1, obj2.attr1 print obj1 is obj2输出结果:
可以看到obj1和obj2是同一个实例。
class Singleton(object): __instance = None def __init__(self, *args, **kwargs): pass def __new__(cls, *args, **kwargs): if not cls.__instance: # if not hasattr(cls, 'instance'): cls.__instance = super(Singleton, cls).__new__(cls, *args, **kwargs) cls.__instance.aa = args[0] print type(cls), type(cls.__instance), type(cls.__instance.aa) return cls.__instance obj1 = Singleton(1, 2, 3, b=2) obj2 = Singleton(1, 2, 3, b=2) obj1.attr1 = 'value1' obj2.attr2 = 'value2' print obj1.attr1, obj1.attr2 print obj1 is obj2 print obj1.aa, obj2.attr1 结果: <type 'type'> <class '__main__.Singleton'> <type 'int'> value1 value2 True 1 value1
(1)Python高级编程技巧:Comprehensions、Decorators、ContextLib、Descriptors、MetaClasses、Patterns
http://blog.jobbole.com/61171/