__new__ __init__ 区别
原文地址: http://stackoverflow.com/questions/674304/pythons-use-of-new-and-init
Use __new__ when you need to control the creation of a new instance. Use __init__ when you need to control initialization of a new instance.
__new__ is the first step of instance creation. It's called first, and is responsible for returning a new instance of your class.
In contrast, __init__ doesn't return anything; it's only responsible for initializing the instance after it's been created.
In general, you shouldn't need to override __new__ unless you're subclassing an immutable type like str, int, unicode or tuple.
__call__ implements function call operator
class foo:
def __call__(self, a, b, c):
# ...
x = foo()
x(1, 2, 3) # __call__
原文地址:http://blog.danmarner.com/me/entry/python-new-metaclass-init-plugin-system/
一个用 class 关键字定义的类在执行a = ClassA(arg1, arg2,...)(初始化其实例)的时候,会发生 :::
a = type(ClassA).__call__(ClassA, arg1, arg2,...)
type(ClassA)实际上返回的是ClassA的metaclass,默认值为type。这个type.__call__的实现可以用如下代码表示(只能表示表示,实际代码都是用C实现的)。
def __call__(cls, *args, **kwargs): result = cls.__new__(cls, *args, **kwargs) if isinstance(result, cls): type(result).__init__(result,*args,**kwargs) return result
也就是说type.__call__先尝试用__new__来创建类的实例,只有__new__返回了类的实例,__init__才会得以应用到实例上
e.g.
class InjectMeta(type): def __new__(cls, name, bases, attrs): print "class:", cls print "name:", name print "bases:", bases print "attrs:", attrs return type.__new__(cls, name, bases, attrs) def __init__(cls, name, bases, attrs): print "class:", cls# cls = Data type.__init__(cls, name, bases, attrs) class Data(object): __metaclass__ = InjectMeta x = 1 def test(self): pass res:
class: <class '__main__.InjectMeta'> name: Data bases: (<type 'object'>,) attrs: {'test': <function test at 0x02B6DDB0>, 'x': 1, '__module__': '__main__', '__metaclass__': <class '__main__.InjectMeta'>} class: <class '__main__.Data'>
我们可以从type类派生出新的 metaclass, 然后通过重新实现__new__, __init__, __call__来实现类或者类实例的生成.
Meta类 meta.py
class Meta(type): def __call__(self): print 'Enter Meta.__call__: ', self obj = type.__call__(self) print 'Exit Meta.__call__: ', obj return obj def __new__(metacls, name, bases, dictionary): print 'Enter Meta.__new__:', metacls, name, bases, dictionary newClass = type.__new__(metacls, name, bases, dictionary) print 'Exit Meta.__new__: ', newClass return newClass def __init__(cls, name, bases, dictionary): print 'Enter Meta.__init__: ', cls, name, bases, dictionary super(Meta, cls).__init__(name, bases, dictionary) print 'Exit Meta.__init__' print 'Create class A' A = Meta('A', (object,), {}) print print 'Create instance of class A' A() 当我们运行上述的python文件, 会得到下面的输出结果: $ python meta.py Create class A Enter Meta.__new__: <class '__main__.Meta'> A (<type 'object'>,) {} Exit Meta.__new__: <class '__main__.A'> Enter Meta.__init__: <class '__main__.A'> A (<type 'object'>,) {} Exit Meta.__init__ Create instance of class A Enter Meta.__call__: <class '__main__.A'> Exit Meta.__call__: <__main__.A object at 0xb76a9ccc>
静态类 (static class): 不允许创建实例,通常作为工具类 (Utility) 存在。
class StaticClassMeta(type): def __new__(cls, name, bases, attr): t = type.__new__(cls, name, bases, attr) def ctor(cls, *args, **kwargs): raise RuntimeError("Cannot create a instance of the static class!") t.__new__ = staticmethod(ctor) return t class Data(object): __metaclass__ = StaticClassMeta >>> Data() RuntimeError: Cannot create a instance of the static class!
密封类 (sealed class): 禁止被继承。
class SealedClassMeta(type): _types = set() def __init__(cls, name, bases, attrs): if cls._types & set(bases): # 判断当前类型基类是否是sealed class。 raise SyntaxError("Cannot inherit from a sealed class!") cls._types.add(cls) # 将当前类型加入到禁用继承集合。 class A(object): __metaclass__ = SealedClassMeta >>> class B(A): pass SyntaxError: Cannot inherit from a sealed class!

浙公网安备 33010602011771号