python基本定制之__new__, __init__

1,官方文档摘要

  • object.``__new__(cls[, ...])

    调用以创建一个 cls 类的新实例。__new__() 是一个静态方法 (因为是特例所以你不需要显式地声明),它会将所请求实例所属的类作为第一个参数。其余的参数会被传递给对象构造器表达式 (对类的调用)。__new__() 的返回值应为新对象实例 (通常是 cls 的实例)。典型的实现会附带适宜的参数使用 super().__new__(cls[, ...]),通过超类的 __new__() 方法来创建一个类的新实例,然后根据需要修改新创建的实例再将其返回。如果 __new__() 返回一个 cls 的实例,则新实例的 __init__() 方法会在之后被执行,例如 __init__(self[,...]),其中 self 为新实例,其余的参数与被传递给 __new__() 的相同。如果 __new__() 未返回一个 cls 的实例,则新实例的 __init__() 方法就不会被执行。__new__() 的目的主要是允许不可变类型的子类 (例如 int, str 或 tuple) 定制实例创建过程。它也常会在自定义元类中被重载以便定制类创建过程。

  • object.``__init__(self[, ...])

    在实例 (通过 __new__()) 被创建之后,返回调用者之前调用。其参数与传递给类构造器表达式的参数相同。一个基类如果有 __init__() 方法,则其所派生的类如果也有 __init__() 方法,就必须显式地调用它以确保实例基类部分的正确初始化;例如: super().__init__([args...]).因为对象是由 __new__()__init__() 协作构造完成的 (由 __new__() 创建,并由 __init__() 定制),所以 __init__() 返回的值只能是 None,否则会在运行时引发 TypeError

2,代码演示

class Students:

    # 用于初始化实例,相当于java的构造函数
    def __init__(self):
        print('init方法')
        print(self)
        print(id(self))

    """
    __new__用法
    用于创建实例,在创建实例的时候自动调用,相当于java的new Xxx()
        1,cls表示当前类Students
        2,super().__new__(cls)表示创建当前类Students类的实例,并返回这个实例
        3,self接受__new__返回的实例,为当前类创建的实例本身,当执行student = Students(),self即为student
    """
    def __new__(cls, *args, **kwargs):
        print('new方法')
        print(cls)
        print(id(cls))
        a = super().__new__(cls)
        print(a)
        print(id(a))
        return a

    # 设计单例模式
    # def __new__(cls, *args, **kwargs):
    #     if not hasattr(cls, 'instance'):
    #         cls.instance = super().__new__(cls)
    #     return cls.instance

print(id(Students)) student = Students() print(student) print(id(student))
 
  
执行的结果:
"""
193802760
new方法
<class '__main__.Students'>
193802760
<__main__.Students object at 0x0B8C9CB0>
193764528
init方法
<__main__.Students object at 0x0B8C9CB0>
193764528
<__main__.Students object at 0x0B8C9CB0>
193764528
"""

 

3,总结

init 和 new 最主要的区别在于:
1.init 通常用于初始化一个新实例,控制这个初始化的过程,比如添加一些属性, 做一些额外的操作,发生在类实例被创建完以后。它是实例级别的方法。
2.new 通常用于控制生成一个新实例的过程。它是类级别的方法。new方法主要是当你继承一些不可变的class时(比如int, str, tuple),
 提供给你一个自定义这些类的实例化过程的途径。还有就是实现自定义的metaclass。

转载于:https://www.cnblogs.com/noperx/p/10997318.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值