如何理解Python中的__new__ 和__init__ 方法

__new____init__ 是两个在类定义中经常遇到但作用完全不同的特殊方法(也称为魔术方法或双下划线方法),在讲解单例模式之前,必须先学习这块的知识

new 的特点

  • new 是一个静态方法(它默认接受 cls 作为第一个参数,代表当前类,此参数在实例化时由Python解释器自动提供),用于创建并返回类的实例。
  • 在对象实例化过程中,new 方法首先被调用,然后才是 init 方法。
  • 默认情况下,new 方法在 object 基类中定义,并返回 cls(即类本身)的一个新实例。但可以通过继承并重写这个方法来自定义实例的创建过程。
  • new 方法必须返回一个类的实例(通常是当前类的实例,但也可以是其他类的实例),否则Python会引发 TypeError。
  • 如果不需要改变实例的创建过程(比如实现单例模式),就不需要重写 new 方法。

init 的特点

  • init 是一个实例方法,用于初始化新创建的对象。
  • new 方法成功返回一个新的实例后,Python会自动调用这个实例的 init 方法(如果存在)。
  • init 方法的主要作用是设置实例的初始状态或执行一些必要的设置。
  • init 方法可以没有返回值(或显式返回 None),因为它不负责创建实例;实例的创建由 new 方法负责。

一句话简单概括:__new__方法创建并返回实例,__init__初始化实例

1、执行顺序,先执行__new__方法,再执行__init__方法

class MyClass:
	def __init__(self):
		print("__init__ running")

	def __new__(cls):
		print("__new__ running")
		return super().__new__(cls)

instance= MyClass()
#__new__ running
#__init__ running

2、new__方法构造一个类实例,并将该实例传递给自身的__init()方法,即__init__()方法的self参数。

class MyClass:
	def __new__(cls):
		print("__new__ running")
		instance = super().__new__(cls)
		print(instance)
		print(type(instance))
		print(id(instance))
		print("\n")
		return instance

	def __init__(self):
		print("__init__ running")
		print(self)
		print(type(self))
		print(id(self))



instance= MyClass()

# __new__ running
# <__main__.MyClass object at 0x000001C906EFCBB0>
# <class '__main__.MyClass'>
# 1962916432816


# __init__ running
# <__main__.MyClass object at 0x000001C906EFCBB0>
# <class '__main__.MyClass'>
# 1962916432816

3、__new__方法必须返回实例,否则__init__方法不被调用

class MyClass:
	def __new__(cls):
		print("__new__ running")
		instance = super().__new__(cls)
		# return instance

	def __init__(self):
		print("__init__ running")
	



instance= MyClass()

# __new__ running

4、如果重写__new__方法,除了cls参数外,还需保持和__init__的其他入参一致

class MyClass:
	def __new__(cls):
		print("__new__ running")
		instance = super().__new__(cls)
		return instance

	def __init__(self,name,age):
		print("__init__ running")
		self.name =name
		self.age = age

instance= MyClass('YANG',99)

#Traceback (most recent call last):
#  File "xxx.py", line 14, in <module>
#    instance= MyClass('YANG',99)
#TypeError: __new__() takes 1 positional argument but 3 were given

正确应该这样写:

class MyClass:
	def __new__(cls,name,age):
		print("__new__ running")
		instance = super().__new__(cls)
		return instance

	def __init__(self,name,age):
		print("__init__ running")
		self.name =name
		self.age = age

instance= MyClass('YANG',99)

或者,推荐这样写:

class MyClass:
	def __new__(cls,*args,**kwargs):
		print("__new__ running")
		instance = super().__new__(cls)
		return instance

	def __init__(self,name,age):
		print("__init__ running")
		self.name =name
		self.age = age

instance= MyClass('YANG',99)


  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

软件测试技术

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值