我们平时都是定义类和方法都是这样的:
class People(object):
def __init__(self, name, age):
self.name = name
self.age = age
print('This is init')
def func(self):
print("This is Test Func")
if __name__ == '__main__':
s = People('张三', 25)
print(s.name)
print(s.age)
s.func()
# This is init
# 张三
# 25
# This is Test Func
但是在使用__init__()方法初始化之前还有一步,那就是__new__()创建实例!
那么什么是__new__()?
1.new()是在类准备将自身实例化时调用,并且至少需要传递一个参数cls,此参数在实例化时由python解释器自动提供;
2.始终是类的静态方法,即使没有被加上静态方法装饰器
3.必须要有返回值,返回实例化出来的实例;可以return父类(通过super(当前类名,cls)).__new__出来的实例,或者直接是object的__new__出来的实例
从object继承
class People(object):
def __new__(cls, *args, **kwargs):
print('This is __new__()') # 这是为了追踪new的执行过程
print(type(cls)) # 这是为了追踪new的执行过程
return object.__new__(cls) # 调用父类的(object)的new方法,返回一个People实例,这个实例传递给init的self参数
def __init__(self, name, age):
self.name = name
self.age = age
print('This is __init__()')
def func(self):
print("This is testfunc")
if __name__ == '__main__':
s = People('Tom', 18)
print(s.name)
print(s.age)
s.func()
# This is __new__()
# <class 'type'>
# This is __init__()
# Tom
# 18
# This is testfunc
从自定义的类继承
class People:
def __new__(cls, *args, **kwargs):
print("This is People's new")
print(type(cls))
return super(People,cls).__new__(cls)
def __init__(self):
print("This is People's init")
class Children(People):
def __init__(self, name, age):
self.name = name
self.age = age
print("This is Children's init")
if __name__ == '__main__':
child = Children('Tom', 18)
print(child.name)
print(child.age)
# This is People's new
# <class 'type'>
# This is Children's init
# Tom
# 18
如果没有返回值,就不能够创建实例,那么在初始化init的时候自然会出错,这就是为什么会报错没有name属性,因为根本没创建成功
class People(object):
def __new__(cls, *args, **kwargs):
print('This is __new__()') # 这是为了追踪new的执行过程
print(type(cls)) # 这是为了追踪new的执行过程
def __init__(self, name, age):
self.name = name
self.age = age
print('This is __init__()')
def func(self):
print("This is testfunc")
if __name__ == '__main__':
s = People('Tom', 18)
print(s.name)
print(s.age)
s.func()
# print(s.name)
# AttributeError: 'NoneType' object has no attribute 'name'
# This is __new__()
# <class 'type'>
__new__不是一定要有的,只有继承自object的类才有,子类如果没有重新定义new,会直接追溯至object的new方法,因为object是所有新式类的基类。子类中如果新写了new,可以自由选择其他的新式类,这也是为什么我们平时没有写__new__也不会报错的原因:会直接追溯至object的new方法,因为object是所有新式类的基类!
init()方法
1.有一个参数self,该self参数就是__new__()返回的实例;2.init()在__new()的基础上完成初始化动作,不需要返回值;
3.若__new__()没有正确返回当前类cls的实例,那__init__()将不会被调用
4.创建的每个实例都有自己的属性,方便类中的实例方法调用
5.init()至少有一个参数self,就是这个__new__()返回的实例__init__()在__new__()的基础上完成一些初始化的操作
总结:
1、创建实例的时候,先new后init
2、new定义在type元类中,必须具有返回值
3、new的作用就是创建实例,然后将创建的实例传递给init进行初始化
4、__new__方法主要是当你继承一些不可变的class时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径,还有就是实现自定义的metaclass
5.自己在定义__new__的时候,参数要与__init__函数的参数匹配,我可以不用到这些参数,但一定要匹配。或者可以使用*arg和**args的形式:*arg可以匹配任意多个未知参数