python __new__

Posted Lippman

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python __new__相关的知识,希望对你有一定的参考价值。

new

This method is only used for new-style classes (classes inheriting from object).
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.

  • 静态方法
  • 构建cls对象
  • 如果__new__返回cls实例,__init__将被调用
  • 如果__new__返回为空,__init__不会被调用
  • init 实例方法,初始化实例

实验

实验1

  • 重写new 但是不返回实例
  • code
  1. class A(object):
  2. a = 1
  3. def __new__(cls, *args, **kwargs):
  4. print ‘+ A new‘
  5. inst = super(A, cls).__new__(cls, *args, **kwargs)
  6. print ‘- A new‘
  7. #return inst
  8. def __init__(self):
  9. print ‘+ A init‘
  10. print ‘- A init‘
  11. a = A()
  12. print type(a)
  13. + A new
  14. - A new
  15. <type ‘NoneType‘>
  • 结论:
    1 new无cls实例返回,初始化实例后将位None
    2 init方法并没有被调用

实验2

  • new 方法重写,调用超类的new并返回实例
  1. class A(object):
  2. a = 1
  3. def __new__(cls, *args, **kwargs):
  4. print ‘+ A new‘
  5. inst = super(A, cls).__new__(cls, *args, **kwargs)
  6. print ‘- A new‘
  7. return inst
  8. def __init__(self):
  9. print ‘+ A init‘
  10. print ‘- A init‘
  11. a = A()
  12. print type(a)
  13. 结果
  14. + A new
  15. - A new
  16. + A init
  17. - A init
  18. <class ‘__main__.A‘>

应用:实现单例

  1. class A(object):
  2. _inst = None
  3. def __new__(cls, *args, **kwargs):
  4. print ‘+ A new‘
  5. if not cls._inst:
  6. print ‘do new.‘
  7. cls._inst = super(A, cls).__new__(cls, *args, **kwargs)
  8. cls._inst.inst_count = 0
  9. print ‘- A new‘
  10. return cls._inst
  11. def __init__(self):
  12. print ‘+ A init‘
  13. self.inst_count += 1
  14. print ‘- A init‘
  15. a = A()
  16. print type(a), a.inst_count
  17. aa = A()
  18. print type(aa), aa.inst_count
  19. aaa = A()
  20. print type(aaa), aaa.inst_count
  • 结果
  1. + A new
  2. do new.
  3. - A new
  4. + A init
  5. - A init
  6. <class ‘__main__.A‘> 1
  7. + A new
  8. - A new
  9. + A init
  10. - A init
  11. <class ‘__main__.A‘> 2
  12. + A new
  13. - A new
  14. + A init
  15. - A init
  16. <class ‘__main__.A‘> 3




以上是关于python __new__的主要内容,如果未能解决你的问题,请参考以下文章

Python中__new__的作用

Python元类的__new__方法中的奇怪行为[重复]

Python中的__init__和__new__

这些 C++ 代码片段有啥作用?

由Python通过__new__实现单例模式,所想到的__new__和__init__方法的区别

python中的__init__和__new__的区别