__new__ 和 __init__

new 在新式类中负责真正的实例化对象,而__init__只是负责初始化 __new__建立的对象。通常来讲 new 建立一个内存对象,也就是实例化的对象的实体,交给__init__进行进一步加工。官方文档以下:html

https://docs.python.org/2/reference/datamodel.html#object.__new__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.

这里有几条很是重要express

  1. new 接受的参数除了 cls 还能够有不少。 剩余的参数实际上是会传递给__init__
  2. new 返回的对象是 cls 的实例,才会调用__init__ 不然就不调用了。

知道了以上信息,咱们能够写一个proxy类, 该类的做用是代理其它任何类。 好比:app

proxy = Proxy(apple)

咱们这里接受了一个对象apple做为参数,那么proxy 就应该有apple的全部属性。 实现方式以下:代理

首先定义一个类,new 方法会接受 cls, target, *args, **kwargs为参数。这里cls 就是Proxy本身,但咱们在真正实例化对象的时候用target的类来实例化。code

class Proxy(object):
    def __new__(cls, target, *args, **kwargs):
        return target.__class__(*args, **kwargs)

接下来定义两个类,有本身的方法htm

class A(object):
    def run(self):
        return 'run'


class B:
    def fly(self):
        return 'fly'

能够看到,咱们能够用proxy 来代理 a,b 由于proxy在实例化的时候实际上借助了a/b对象

a = A()
b = B()

pa = Proxy(a)
pb = Proxy(b)
print "pa.run is ", pa.run()
print "pb.fly is ", pb.fly()
相关文章
相关标签/搜索