1、定义

__new__:构造方法(负责对象的创建), 通常用于控制生成一个新实例的过程。它是类级别的方法,是一个静态方法。

__init__:初始化方法( 负责对象的初始化),通常用于初始化一个新实例,控制这个初始化的过程,比如添加一些属性, 做一些额外的操作,发生在类实例被创建完以后。它是实例级别的方法,是一个实例方法。

 

2、区别

触发时机

__new__:创建一个新实例花对象时触发__new__,生成一个新实例

__init__:实例化对象生成后触发__init__,来进行实例的初始化

当二者同时存在且new返回的是本类实例对象时,new先触发,init再new后面触发;

当二者同时存在且new返回的是其他类实例对象时,new先触发,init不触发;

 

传参

__new__:必须传参,必须传入cls,其他参数酌情传参

__init__:不必须传参,可以不进行传参

ios init方法的中调用self. __init__ 方法如何定义_初始化方法

 

 

 

ios init方法的中调用self. __init__ 方法如何定义_python基础_02

 

 

 

返回值:

__new__:至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供,__new__必须要有返回值,返回实例化出来的实例,可以return父类__new__出来的实例,或者直接是object的__new__出来的实例。

根据传参返回的实例对象,如果返回的是本类实例对象时,才会调用本类的初始化方法(__init__);如果返回的是其他类的实例对象,则不会调用本类的初始化方法(__init__)

__init__:没有返回值

 

案例集锦:

1、new返回本类对象实例,此时触发本类中的init方法

### 单例模式
# 创建类B
class B():

  # 初始化方法
  def __init__(self):
    self.ccc = 2
    self.ddd = 3

  def run2(self):
    print(8888888888888888888888888888888)

 

# 创建类A
class A():

  # 私有属性
  _obj = None

  # 构造方法
  def __new__(cls, *args, **kwargs):
    if cls._obj == None:
      cls._obj = super().__new__(cls) # 传参传的cls是本类对象,且最后return返回本类对象实例
    return cls._obj 
    # return object.__new__(B)

  # 初始化方法

  def __init__(self):
    self.a = 2
    self.b = 3

  def run(self):
    print(222222222222222222222222)

 

# 测试

# 无论实例多少次,id都是指向同一个地址,实现单例模式

aaa = A()
bbb = A()
ccc = A()
ddd = A()

print(id(aaa))
print(id(bbb))
print(id(ccc))
print(id(ddd))
print(type(aaa))

 

# 调用本类中的方法、属性

print(aaa.a)
print(aaa.b)
print(aaa.run())

### 非单例模式
# 创建类B
class B():

  # 初始化方法
  def __init__(self):
    self.ccc = 2
    self.ddd = 3

  def run2(self):
    print(8888888888888888888888888888888)

 

# 创建类A
class A():

  # 私有属性
  _obj = None

  # 构造方法
  def __new__(cls, *args, **kwargs):
    # if cls._obj == None:
      # cls._obj = super().__new__(cls) # 传参传的cls是本类对象,且最后return返回本类对象实例
    # return cls._obj 
    # return object.__new__(B)

    return super().__new__(cls) # 传参传的cls是本类对象,且最后return返回本类对象实例,非单例模式

  # 初始化方法

  def __init__(self):
    self.a = 2
    self.b = 3

  def run(self):
    print(222222222222222222222222)

 

# 测试

# 无论实例多少次,id都是指向同一个地址,实现单例模式

aaa = A()
bbb = A()
ccc = A()
ddd = A()

print(id(aaa))
print(id(bbb))
print(id(ccc))
print(id(ddd))
print(type(aaa))

 

# 调用本类中的方法、属性

print(aaa.a)
print(aaa.b)
print(aaa.run())

 


 

 

2、new返回其他类对象实例,本类中的init方法不触发,可调用B类的属性、方法

# 创建类B
class B():

  g = 55

  h = 66

  def run2(self):
    print(8888888888888888888888888888888)

 

# 创建类A
class A():

  # 私有属性
  _obj = None

  # 构造方法
  def __new__(cls, *args, **kwargs):
    # if cls._obj == None:
      # cls._obj = super().__new__(cls) # 传参传的cls是本类对象,且最后return返回本类对象实例
    # return cls._obj 

    # return super().__new__(cls) # 传参传的cls是本类对象,且最后return返回本类对象实例,非单例模式

    return object.__new__(B, *args, **kwargs) # 传参传的其他类对象B,最后return返回B类对象实例,可调用B类的方法、属性

  

  # 初始化方法

  def __init__(self):
    self.a = 2
    self.b = 3

  def run(self):
    print(222222222222222222222222)

 

# 测试

# 无论实例多少次,id都是指向同一个地址,实现单例模式

aaa = A()
bbb = A()
ccc = A()
ddd = A()

print(id(aaa))
print(id(bbb))
print(id(ccc))
print(id(ddd))
print(type(aaa))

 

# 调用B类中的方法、属性

print(bbb.g)
print(bbb.h)
bbb.run2()

 注意:如果new()没有返回cls(即当前类)的实例,那么当前类的init()方法是不会被调用 的。如果new()返回其他类(新式类或经典类均可)的实例,那么只会调用被返回的那个类的构造方 法。