这篇文章的目的是在python3环境下, 讨论__new__
和__init__
方法的用法。
new和init的差异
__new__
和__init__
方法都是类的内置方法, 他们的主要区别是: __new__
用于对象的创建, 而__init__
用于对象的实例化, 所以你可以猜到, __new__
在__init__
之前被调用。 所以我们如果想要改变类的创建过程, 可以自定义__new__
方法, 比如动态创建对象(对象的类型是可变的)。
1 | class A: |
输出(plain):
<__main__.A at 0x22fb59938d0>
<__main__.A at 0x22fb59938d0>
1 | ABC('B') |
输出(plain):
<__main__.B at 0x22fb59671d0>
<__main__.B at 0x22fb59671d0>
1 | ABC('C') |
输出(plain):
<__main__.C at 0x22fb5bfcbe0>
<__main__.C at 0x22fb5bfcbe0>
通过上面的例子, 你可能已经发现, __new__
的第一个参数是类本身, 而__init__
是实例本身。 你需要注意的是, __new__
返回的实例不是自己的实例时, __init__
方法不会被调用, 而如果返回的是自己的实例时, 就可以被隐性调用:
1 | ABC('ABC') |
输出(stream):
Befor new
After new
Hi ABC
Befor new
After new
Hi ABC
输出(plain):
<__main__.ABC at 0x22fb5bfd780>
<__main__.ABC at 0x22fb5bfd780>
所以, 当返回其他类的实例时, 你需要自己调用__init__
方法:
1 | class A: |
输出(stream):
I am in A
I am in A
输出(plain):
<__main__.A at 0x22fb59677b8>
<__main__.A at 0x22fb59677b8>
应用
我常常在使用单例模式的时候自定义__new__
方法, 单例模式的意思就是类只能实例化得到一个实例, 多次实例化返回的还是同一个实例:
1 | class Singleton(object): |
1 | s1 = Singleton() |
输出(stream):
I am in A
I am in A
a1 == a2: False
s1 == s2: True
I am in A
I am in A
a1 == a2: False
s1 == s2: True
参考文献
- https://howto.lintel.in/python-__new__-magic-method-explained/
- https://spyhce.com/blog/understanding-new-and-init
注意
本文由jupyter notebook转换而来, 您可以在这里下载notebook
统计咨询请加QQ 2726725926, 微信 mllncn, SPSS统计咨询是收费的
微博上@mlln-cn可以向我免费题问
请记住我的网址: mlln.cn 或者 jupyter.cn