您的位置:首页 > 编程语言 > Python开发

python __init__和__new__之间的区别

2011-10-09 16:08 477 查看
1 如果在类中同时定义了__init__和__new__,在创建对象的时候会有优先使用__new__



class A(object):

def __init__(self):

print("in init")

def __new__(self):

print("in new")

A()

2new方法会返回所构造的对象,init则不会,在使用new返回对象的时候会隐式调用init函数。new函数必须以cls作为第一个参数,而init则以self作为其第一个参数

实例:

class A(object):

def __new__(cls, *args, **kwds):

print "one"

print "A.__new__", args, kwds

return object.__new__(B, *args, **kwds)

def __init__(cls, *args, **kwds):

print "two"

print "A.__init__", args, kwds

class B(object):

def __new__(cls, *args, **kwds):

print "three"

print cls

print B

print "B.__new__", args, kwds

return object.__new__(cls, *args, **kwds)

def __init__(cls, *args, **kwds):

print "four"

print "B.__init__", args, kwds

class C(object):

def __init__(cls, *args, **kwds):

print "five"

print "C.__init__", args, kwds

print C()

print "====================="

print A()

print "====================="

print B()

利用new创建一个类的对象的最常用的方法为:super(currentclass, cls).__new__(cls[, ...])

如下列

class A(object):

def __new__(cls):

Object = super(A, cls).__new__(cls)

print "in New"

return Object

def __init__(self):

print "in init"

class B(A):

def __init__(self):

print "in B's init"

B()

来自Python文档:

object.__new__(cls[, ...])

Called to create a new instance of class cls. __new__() is a static method (special-cased so you need not declare it as such) that takes the class of which an instance was requested as its first argument. The remaining arguments are those passed to the object
constructor expression (the call to the class). The return value of __new__() should be the new object instance (usually an instance of cls).

Typical implementations create a new instance of the class by invoking the superclass’s __new__() method using super(currentclass, cls).__new__(cls[, ...]) with appropriate arguments and then modifying the newly-created instance as necessary before returning
it.

If __new__() returns an instance of cls, then the new instance’s __init__() method will be invoked like __init__(self[, ...]), where self is the new instance and the remaining arguments are the same as were passed to __new__().

If __new__() does not return an instance of cls, then the new instance’s __init__() method will not be invoked.

__new__() is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation. It is also commonly overridden in custom metaclasses in order to customize class creation.

object.__init__(self[, ...])

Called when the instance is created. The arguments are those passed to the class constructor expression. If a base class has an __init__() method, the derived class’s __init__() method, if any, must explicitly call it to ensure proper initialization of the
base class part of the instance; for example: BaseClass.__init__(self, [args...]). As a special constraint on constructors, no value may be returned; doing so will cause a TypeError to be raised at runtime.

补充一个例子:

When subclassing immutable built-in types like numbers and strings, and occasionally in other situations, the static method __new__ comes in handy. __new__ is the first step in instance construction, invoked before __init__. The __new__ method is called
with the class as its first argument; its responsibility is to return a new instance of that class.
Compare this to __init__: __init__ is called with an instance as its first argument, and it doesn't return anything; its responsibility is to initialize the instance.
There are situations where a new instance is created without calling __init__ (for example when the instance is loaded from a pickle). There is no way to create a new instance without calling __new__ (although in some cases you can get away with calling
a base class's __new__).

Recall that you create class instances by calling the class. When the class is a new-style class, the following happens when it is called. First, the class's __new__ method is called, passing the class itself as first argument, followed by any (positional as
well as keyword) arguments received by the original call. This returns a new instance. Then that instance's __init__ method is called to further initialize it. (This is all controlled by the __call__ method of the metaclass, by the way.)

Here is an example of a subclass that overrides __new__ - this is how you would normally use it.

>>> class inch(float):

... "Convert from inch to meter"

... def __new__(cls, arg=0.0):

... return float.__new__(cls, arg*0.0254)

...

>>> print inch(12)

0.3048

>>>

This class isn't very useful (it's not even the right way to go about unit conversions) but it shows how to extend the constructor of an
immutable type. If instead of __new__ we had tried to override __init__, it wouldn't have worked:

>>> class inch(float):

... "THIS DOESN'T WORK!!!"

... def __init__(self, arg=0.0):

... float.__init__(self, arg*0.0254)

...

>>> print inch(12)

12.0

>>>

The version overriding __init__ doesn't work because the float type's __init__ is a no-op: it returns immediately, ignoring its arguments.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: