python3中_new_和_init_的不同

python3中_new_和_init_的不同:

 原理:类创建对象时,若类中定义了_init_方法(重写了父类的_init_方法,会覆盖父类的_init_方法,但通过super()方法也可以继承父类的_init_方法),但没定义_new_方法,会自动调用父类object的_new_方法通过系统的方式创建对象,对象一创建完会自动调用类中定义的_init_方法.

class Dog(object):
    def __init__(self):
        '对象一创建完就会调用'
        print('对象初始化')
dog1 = Dog()
  打印结果:

对象初始化

class Dog(object):
    def __new__(cls, *args, **kwargs):
        #创建对象时调用
        print('创建对象')
        return '1'
    def __init__(self):
        '对象一创建完就会调用'
        print('对象初始化')
dog1 = Dog()
print(dog1)
打印结果:

创建对象
1

因为不是按照系统的方式创建对象,所以就不会调用_init_方法

#用汉字模拟通过系统的方式创建对象即默认的object类中_new_方法创建对象
# class object:
#     def __new__(cls, *args, **kwargs):
#         print("创建对象")
#         return "系统的方式创建的对象"

class Dog(object):
    def __new__(cls, *args, **kwargs):
        #创建对象时调用
        print('创建对象')
        #返回默认的父类object通过_new__方法创建的对象,即通过系统的方式创建的对象
        return object.__new__(cls)
    def __init__(self):
        '对象一创建完就会调用'
        print('对象初始化')
dog1 = Dog()
print(dog1)
打印结果:

创建对象
对象初始化
<__main__.Dog object at 0x000000000290B898>

class Dog(object):
    def __new__(cls, *args, **kwargs):
        #创建对象时调用
        print('创建对象')
        #会将返回值提供给引用对象变量
        return '1'
    def __init__(self):
        '对象一创建完就会调用'
        print('对象初始化')
dog1 = Dog()
print(dog1)
打印结果:

创建对象
1

不按系统方式创建对象,返回对象'1',就不会调用_init_方法

"""类方法"""
# class Dog:
#     __type = "狗"  # 类属性
#
#     #  类方法: 和类属性配合使用,想要访问或者修改类属性时,可以定义类方法
#     @classmethod  # 方法上边添加 @classmethod 标识,就会自动生成类方法
#     def get_type(cls):  # 类方法会自动设置第一个形参为cls,调用时自动设置类对象为第一个实参
#         return cls.__type
#
#
# # 调用类方法 对象名和类名都可以访问
# dog1 = Dog()
# result = Dog.get_type()
# result = dog1.get_type()
# print(result)
class Dog(object):
    __type = '狗'#类属性
    def __new__(cls, *args, **kwargs):
        #创建对象时调用
        print('创建对象')
        #会将返回值提供给引用对象变量
        return cls.__type
    def __init__(self):
        '对象一创建完就会调用'
        print('对象初始化')
dog1 = Dog()
print(dog1)
打印结果:

创建对象

(1)

_new_方法是在创建对象时调用的;

_init_方法是在对象一创建完就调用,而且只有通过系统的方法创建的对象才会执行_init_方法,object默认的_new_方法会先于_init_方法调用

(2)

_new_方法的形参是类,而_init_方法的形参是对象


### `__new__` `__init__` 的区别 #### 作用与职责 `__new__` 是一个静态方法,负责创建类的实例对象。它在对象实例化过程中首先被调用,并返回一个实例。如果返回的不是当前类的实例,则不会调用 `__init__`[^4]。 `__init__` 是一个实例方法,用于初始化已被创建的对象实例。它在 `__new__` 返回实例后自动调用,通常用于设置对象的属性或执行初始化逻辑[^1]。 #### 调用顺序 `__new__` 在对象创建之前被调用,而 `__init__` 在对象创建之后被调用。两者的协作流程如下: 1. 当使用 `ClassName()` 实例化对象时,首先调用 `__new__` 创建实例。 2. 如果 `__new__` 返回的是当前类的实例,则继续调用 `__init__` 对该实例进行初始化[^3]。 #### 参数返回值 `__new__` 接收的第一个参数是类本身(`cls`),随后可以接收任意数量的位置参数关键字参数。它必须返回一个实例对象,通常是当前类的实例[^4]。 `__init__` 接收的第一个参数是实例对象(`self`),随后是与 `__new__` 相同的参数列表。它不返回任何值,若尝试返回非 `None` 值将引发异常[^4]。 #### 使用场景 `__new__` 通常用于需要控制对象创建过程的场景,例如单例模式、不可变类型子类化、对象池或缓存等[^4]。以下是一个实现单例模式的示例: ```python class Singleton: _instance = None def __new__(cls): if not cls._instance: cls._instance = super().__new__(cls) return cls._instance ``` `__init__` 更为常见,适用于大多数对象初始化需求,如设置属性、配置初始状态等。例如: ```python class Person: def __init__(self, name, age): self.name = name self.age = age ``` #### 注意事项 除非有特殊需求,否则应优先使用 `__init__`。重写 `__new__` 可能会影响对象创建的核心机制,容易引入难以调试的问题,因此需谨慎使用[^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值