python新式类中的__new__方法与__init__方法
Posted bitcarmanlee
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python新式类中的__new__方法与__init__方法相关的知识,希望对你有一定的参考价值。
1.旧式类
在讲新式类之前,先看看旧式类是怎么用的。
class OldClass:
pass
OldClass()
上面就是旧式类的写法,默认继承type类。
2.新式类
python2中,如果定义一个新式类
class NewClass(object):
pass
而在python3中,所有的类,均默认继承object,所以括号里也可以不显示指定object。
3.__new__方法与__init__方法
如果我们再IDE里面输入__new__字样,IDE会自动给我们补全方法如下:
class NewClass(object):
def __new__(cls, *args, **kwargs):
super().__new__()
而如果是输入__init__字样,IDE会自动给我们补全方法如下:
class NewClass(object):
def __new__(cls, *args, **kwargs):
super().__new__()
def __init__(self):
pass
先说结论:
__new__的第一个参数是cls(当然你也可以叫别的名字,但是cls是约定俗成),是用来创建类的实例的(constructor)。
__init__的第一个参数是self,是用来初始化实例的(initializer),这个实例的名字就是self。
class NewClass(object):
def __new__(cls, *args, **kwargs):
print("this is __new__ method!")
instance = super(NewClass, cls).__new__(cls)
return instance
def __init__(self):
print("this is __init__ method!")
pass
NewClass()
代码的输出为:
this is __new__ method!
this is __init__ method!
从上面代码的执行结果可以看出,在创建NewClass类实例并初始化的过程中,__new__方法与__init__方法都被调用了。先是通过__new__方法创建了一个类实例,然后再通过__init__方法初始化。
如果我们把__new__方法中的return一行去掉,不返回任何对象,则__init__方法不会被调用!
class NewClass(object):
def __new__(cls, *args, **kwargs):
print("this is __new__ method!")
instance = super(NewClass, cls).__new__(cls)
def __init__(self):
print("this is __init__ method!")
print("self is: ", self)
pass
NewClass()
代码输出结果为
this is __new__ method!
如果__new__方法返回一个已经存在的对象,不管该对象是什么类型,__init__方法也不会被调用。
s = "abc"
class NewClass(object):
def __new__(cls, *args, **kwargs):
print("this is __new__ method!")
instance = super(NewClass, cls).__new__(cls)
return s
def __init__(self):
print("this is __init__ method!")
print("self is: ", self)
pass
NewClass()
代码输出结果为
this is __new__ method!
4.__init__必须返回None
在__init__方法中,返回类型必须为None。看如下代码
class NewClass(object):
def __new__(cls, *args, **kwargs):
instance = super(NewClass, cls).__new__(cls)
return instance
def __init__(self):
return "abc"
NewClass()
执行结果如下:
TypeError: __init__() should return None, not 'str'
5.__new__方法的作用
按照python官方文档的解释,__new__方法主要是当你继承一些不可变的class时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径。
class PositiveNum(int):
def __new__(cls, value):
return super().__new__(cls, abs(value))
num = PositiveNum(-10)
print(num)
上面的例子,就是通过重写new方法,得到了一个正整数的类。
6.__new__实现单例模式
我们可以通过new方法,来实现一个单例模式。
class Singleton(object):
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls, *args, **kwargs)
return cls._instance
def test_singleton():
s1 = Singleton()
s2 = Singleton()
print(s1)
print(s2)
test_singleton()
<__main__.Singleton object at 0x116e65a50>
<__main__.Singleton object at 0x116e65a50>
通过上面的例子可以看出来,s1与s2的内存地址一样,指向的是同一个实例对象。
7.工厂模式
class Bird(Animal):
def __init__(self):
pass
def print_name(self):
print("my name is Bird!")
class Cat(Animal):
def __init__(self):
pass
def print_name(self):
print("my name is Cat!")
class Factory(object):
animals = "bird": Bird, "cat": Cat
def __new__(cls, name):
if name in cls.animals.keys():
return cls.animals[name]()
else:
return Animal
def test_factory():
bird = Factory("bird")
cat = Factory("cat")
bird.print_name()
cat.print_name()
test_factory()
my name is Bird!
my name is Cat!
以上是关于python新式类中的__new__方法与__init__方法的主要内容,如果未能解决你的问题,请参考以下文章