博客
关于我
__init__ 和 __new__(重点)
阅读量:286 次
发布时间:2019-03-01

本文共 2077 字,大约阅读时间需要 6 分钟。

Python中的__new____init__方法在对象创建过程中起着关键作用。__new__方法在对象被创建之前被调用,负责返回一个新的对象实例,而__init__方法在对象创建之后被调用,用来初始化对象的属性和状态。理解这两者的区别和顺序对编写高效且可靠的Python代码至关重要。

__new__方法的作用

__new__方法是对象创建之前被调用的类方法。它的主要职责是创建一个对象实例,并返回这个实例。__new__方法的定义为:

def __new__(cls, *args, **kwargs):    # 代码逻辑    return obj

其中,cls参数表示当前类,argskwargs是用于传递额外参数和关键字参数。__new__方法必须返回一个实例,这个实例可以是当前类的实例,也可以是其他类的实例,甚至是直接从object类创建的实例。

如果一个类没有自定义__new__方法,Python会使用其父类的__new__方法,依次递归,直到object类的__new__方法被调用。object类的__new__方法返回一个新的不带类型的对象实例。

__init__方法的作用

__init__方法是在对象被创建之后被调用的实例方法。它的主要职责是初始化对象的属性和状态。__init__方法的定义为:

def __init__(self, name):    # 代码逻辑    self.name = name

这里的self参数是指当前实例,即__new__方法返回的实例。__init__方法通常用于将传入的参数赋值给实例的属性,设置初始状态。

如果__new__方法返回一个不是当前类的实例(例如返回字符串或其他类型),那么__init__方法不会被自动调用。这意味着任何自定义的__init__方法都不会执行,可能导致对象属性未能正确初始化。

__new____init__的执行顺序

在Python中,__new__方法总是在__init__方法之前被调用。__new__的返回值决定了是否会调用__init__方法。如果__new__返回一个当前类的实例,那么__init__方法会被自动调用;否则,__init__不会被调用。

示例分析

考虑以下Person类的定义:

class Person:    def __init__(self, name):        print("触发__init__")        self.name = name    def __new__(cls, *args, **kwargs):        print("触发__new__")        obj = super(Person, cls).__new__(cls)        return obj

当执行p = Person("淘小欣")时,首先会调用Person.__new__(),创建一个新的Person实例,然后再调用Person.__init__(),将name属性初始化为"淘小欣"。

如果__new__方法返回一个非Person实例(例如返回字符串"淘小欣"),那么__init__方法不会被调用,导致p.name可能无法访问,出现AttributeError

继承类的处理

在继承关系中,子类的__new__方法会调用父类的__new__方法,除非被显式地重写。例如:

class Str:    passclass Person(Str):    def __new__(cls, *args, **kwargs):        obj = super(Str, cls).__new__(cls)        print(obj.__class__)        return obj    def __init__(self, name):        print("触发__init__")        self.name = name

在上述代码中,Person继承自Str,并在__new__方法中调用Str__new__方法。这样,obj将是Str实例,而不是Person实例。这意味着Person.__init__不会被调用,p.name同样会抛出AttributeError

返回值的重要性

__new__方法必须返回一个实例对象,否则会导致错误。在编写__new__方法时,必须确保返回的是一个正确的对象实例。如果返回的是非对象类型(如字符串、数字等),则可能导致后续的__init__方法无法正确执行。

总结

__new____init__是Python中对象创建过程中的两个关键步骤。__new__负责创建对象实例,而__init__则负责初始化对象的属性和状态。理解这两者的区别和执行顺序对于编写高效且可靠的Python代码至关重要。在实际编码中,应谨慎处理__new____init__的返回值,确保它们正确地创建和初始化对象。

转载地址:http://amto.baihongyu.com/

你可能感兴趣的文章
Openlayers实战:输入WKT数据,输出GML、Polyline、GeoJSON格式数据
查看>>
Openlayers实战:选择feature,列表滑动,定位到相应的列表位置
查看>>
Openlayers实战:非4326,3857的投影
查看>>
Openlayers高级交互(1/20): 控制功能综合展示(版权、坐标显示、放缩、比例尺、测量等)
查看>>
Openlayers高级交互(10/20):绘制矩形,截取对应部分的地图并保存
查看>>
Openlayers高级交互(11/20):显示带箭头的线段轨迹,箭头居中
查看>>
Openlayers高级交互(12/20):利用高德逆地理编码,点击位置,显示坐标和地址
查看>>
Openlayers高级交互(13/20):选择左右两部分的地图内容,横向卷帘
查看>>
Openlayers高级交互(14/20):汽车移动轨迹动画(开始、暂停、结束)
查看>>
Openlayers高级交互(15/20):显示海量多边形,10ms加载完成
查看>>
Openlayers高级交互(16/20):两个多边形的交集、差集、并集处理
查看>>
Openlayers高级交互(17/20):通过坐标显示多边形,计算出最大幅宽
查看>>
Openlayers高级交互(18/20):根据feature,将图形适配到最可视化窗口
查看>>
Openlayers高级交互(19/20): 地图上点击某处,列表中显示对应位置
查看>>
Openlayers高级交互(2/20):清除所有图层的有效方法
查看>>
Openlayers高级交互(20/20):超级数据聚合,页面不再混乱
查看>>
Openlayers高级交互(3/20):动态添加 layer 到 layerGroup,并动态删除
查看>>
Openlayers高级交互(4/20):手绘多边形,导出KML文件,可以自定义name和style
查看>>
Openlayers高级交互(5/20):右键点击,获取该点下多个图层的feature信息
查看>>
Openlayers高级交互(6/20):绘制某点,判断它是否在一个电子围栏内
查看>>