要点
__new__()是创建对象的构造函数,而__init()__是初始化函数;
__new__()返回的对象即为self;
__new__()会自动调用__init()__。
简单例子
class Person(object):
def __new__(cls, name, age):
print(cls)
print('__new__ is called')
# test = super().__new__(cls)
# return test
return super().__new__(cls) # object.__new__() receives only one para
def __init__(self, name, age):
print('__init__ is called')
self.name = name
self.age = age
def __str__(self):
return('<Person: %s(%s)>' % (self.name, self.age))
name = Person('Tom', 24)
print(name)
__new__()创建了Person实例,其返回值其赋值给self。然后自动调用__init()__,且参数self为__new__()返回值,name和age来自于__new__()的参数。注意object.__new()__只接受cls参数,而cls参数是由解释器自动赋值的。
子类调用父类__new()__
import datetime
class MfDateSub(datetime.date):
def __init__(self, year, month, day):
super().__new__(datetime.date, year, month, day)
def next_day(self):
result = datetime.date(self.year, self.month, self.day+1)
return result
mfdate = MfDateSub(2018, 11, 4)
print(mfdate.next_day())
而datetime包中date类并无__init()__,只有__new__():
class date:
def __new__(cls, year, month=None, day=None):
"""Constructor.
Arguments:
year, month, day (required, base 1)
"""
if month is None and isinstance(year, bytes) and len(year) == 4 and \
1 <= year[2] <= 12:
# Pickle support
self = object.__new__(cls)
self.__setstate(year)
self._hashcode = -1
return self
year, month, day = _check_date_fields(year, month, day)
self = object.__new__(cls)
self._year = year
self._month = month
self._day = day
self._hashcode = -1
return self
MfDateSub的作用是扩展date类为其增加next_day功能。MfDateSub的__init()__只能调用date的__new__(),而date的__new__()调用object的__new__()将其赋值给date的self。MfDateSub继承了date,也继承了date的self。所以,MfDateSub的__init()__执行后,就有了date的self。
参考资料
[1] new and init in Python
[2] python的__new__方法
[3] The Python Language Reference, Data Model, object.new(cls[, …])
本文深入解析Python中__new__与__init__的区别与联系,阐述__new__作为对象创建的构造函数,__init__作为初始化函数的角色。通过具体示例展示__new__如何创建对象并返回self,以及如何自动调用__init__进行初始化。同时,探讨子类如何调用父类的__new__方法。
1887

被折叠的 条评论
为什么被折叠?



