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方法进行解析和初始化。
原创文章,作者:XJAYV,如若转载,请注明出处:https://www.506064.com/n/375637.html