Python中的__new__和__init__ 以及self理解

Python中的__new__和__init__

写了这么多的class,现在才知道还有个__new__方法, 那么它和__init__有什么区别呢?

classTestCls():"""docstring for TestCls"""def__init__(self, name):print('init')        print(self)        print(type(self))        self.name = namedef__new__(cls, name):print('new')        print(cls)        print(type(cls))returnsuper().__new__(cls)c = TestCls("CooMark")# new...# # # init...# <__main__.TestCls object at 0x02201130>#

异同点

参数

__new__的第一个占位参数是class对象

__init__的第一个占位参数是class的实例对象

其他的参数应一致

作用

__new__ 用来创建实例,在返回的实例上执行__init__,如果不返回实例那么__init__将不会执行

__init__ 用来初始化实例,设置属性什么的

利用__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.

依照Python官方文档的说法,__new__方法主要是当你继承一些不可变的class时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径。还有就是实现自定义的metaclass。

继承不可变class 参考

假如我们需要一个永远都是正数的整数类型,通过集成int,我们可能会写出这样的代码

classPositiveInteger(int):def__init__(self, value):super().__init__(self, abs(value))i = PositiveInteger(-3)print(i)# # TypeError: object.__init__() takes no parametersclassPositiveInteger(int):def__new__(cls, value):returnsuper(PositiveInteger, cls).__new__(cls, abs(value))i = PositiveInteger(-3)print(i)# 3

用__new__来实现单例

classSingleton(object):def__new__(cls):# 关键在于这,每一次实例化的时候,我们都只会返回这同一个instance对象ifnothasattr(cls,'instance'):            cls.instance = super(Singleton, cls).__new__(cls)returncls.instanceobj1 = Singleton()obj2 = Singleton()obj1.attr1 ='value1'print( obj1.attr1, obj2.attr1)print( obj1isobj2)

你可能感兴趣的:(Python中的__new__和__init__ 以及self理解)