首页 > 编程知识 正文

Python中new和init的区别

时间:2023-11-21 16:18:17 阅读:292232 作者:OTJC

new和init都是Python中常用的魔法方法,它们分别负责对象的创建和初始化,本文将从多个角度详细阐述它们的区别。

一、创建对象

new方法是用来创建一个对象的,它是一个类级别的方法,第一个参数是cls,代表当前类。当使用类名来创建一个对象时,Python首先会调用new方法来创建该对象,然后再调用init方法来进行初始化。

class Person:
    def __new__(cls, *args, **kwargs):
        print('Creating object')
        return super().__new__(cls)

    def __init__(self, name, age):
        print('Initializing object')
        self.name = name
        self.age = age

p = Person('Mike', 25)

在上述代码中,我们在new方法中打印了一条消息来确认创建对象过程的发生。当我们运行这段代码时,会发现在创建对象之前,Python会打印出 "Creating object",然后在调用完init方法之后,会打印出 "Initializing object"。

二、初始化对象

与new方法不同,init方法是用来初始化对象的。这个方法可以被看作是实例级别的构造函数,它会在对象创建完毕后自动被调用。

class Person:
    def __new__(cls, *args, **kwargs):
        print('Creating object')
        return super().__new__(cls)

    def __init__(self, name, age):
        print('Initializing object')
        self.name = name
        self.age = age

p = Person('Mike', 25)
print(p.name, p.age)

在上述代码中,我们在init方法中初始化了对象的两个属性 name 和 age,并通过对象的引用打印出了它们的值。

三、返回对象

在new方法中,我们需要返回一个对象,否则Python解释器不会调用init方法。这个返回值可以是任何对象,值得注意的是,如果返回的对象不是当前类的实例,那么init方法也不会被调用。

class Singleton:
    __instance = None

    def __new__(cls, *args, **kwargs):
        if cls.__instance is None:
            print('Creating object')
            cls.__instance = super().__new__(cls)
        return cls.__instance

    def __init__(self, name):
        print('Initializing object')
        self.name = name

s1 = Singleton('obj1')
s2 = Singleton('obj2')
print(s1.name, s2.name)

在上述代码中,我们创建了一个名为 Singleton 的 Singleton 模式类,它的实例始终只有一个。当我们创建第一个对象时,Python会调用new方法来创建这个对象,随后会调用init方法进行初始化,并将这个对象赋值给类变量 __instance。当我们创建第二个对象时,Python会首先调用new方法来尝试创建这个对象,但是由于 __instance 已经有了值,所以不会再调用init方法,而是直接返回类变量 __instance 的值。这样,我们就实现了单例模式。

四、参数传递

在实例化对象时,我们可以在类名后的括号中传递参数,Python会将这些参数传递给new方法,并从这些参数中解析出init方法需要的参数。

class Person:
    def __new__(cls, *args, **kwargs):
        print('Creating object')
        return super().__new__(cls)

    def __init__(self, name, age):
        print('Initializing object')
        self.name = name
        self.age = age

p = Person('Mike', 25)
print(p.name, p.age)

在上述代码中,我们在创建对象时传递了两个参数,一个是字符串类型的 name,一个是整型的 age。Python会将这两个参数传递给new方法,并解析出它们,随后再将它们传递给init方法进行初始化。

五、派生子类

在派生子类时,我们需要显式地调用父类的new方法和init方法,以便能够正确地创建和初始化对象。

class Animal:
    def __new__(cls, *args, **kwargs):
        print('Creating Animal object')
        return super().__new__(cls)

    def __init__(self, name):
        print('Initializing Animal object')
        self.name = name

class Dog(Animal):
    def __new__(cls, *args, **kwargs):
        print('Creating Dog object')
        return super().__new__(cls)

    def __init__(self, name, breed):
        super().__init__(name)
        print('Initializing Dog object')
        self.breed = breed

d = Dog('Tom', 'Poodle')
print(d.name, d.breed)

在上述代码中,我们定义了一个名为 Animal 的基类和一个名为 Dog 的派生类。当我们创建一个名为 d 的 Dog 对象时,Python首先会调用Dog的new方法来创建这个对象,随后会调用Dog的init方法进行初始化。在Dog的init方法中,我们调用了Animal的init方法来对对象进行初始化。

六、总结

在Python中,new和init都是常用的魔法方法,它们分别负责对象的创建和初始化。new方法是类级别的方法,用来创建对象,init方法是实例级别的方法,用来初始化对象。在使用new方法创建对象时,需要返回一个对象,并在返回之前调用它的init方法。在实例化对象时,我们可以传递参数,并将这些参数传递给new方法进行解析和初始化。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。