获取Pyhon及副业知识,关注公众号【软件测试圈】
大家好,在Python的面向对象编程中,我们常常会遇到两个非常重要的魔法方法:__init__ 和 __new__。这两个方法虽然名字相似,但它们的功能却截然不同。

区别
1. __init__ 方法
__init__ 是一个对象初始化方法,当我们创建一个类的实例时,这个方法会被自动调用。它的主要作用是对实例进行初始化,比如为实例属性赋值。需要注意的是,__init__ 方法并不是真正创建实例的方法,它只是对已经创建好的实例进行一些初始化操作。
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
# 创建实例
dog = Animal("Buddy", 5)
print(dog.name) # 输出: Buddy
print(dog.age) # 输出: 5
在这个例子中,__init__ 方法为 Animal 类的实例 dog 设置了 name 和 age 属性。
2. __new__ 方法
__new__ 是一个静态方法,它是真正创建实例的方法。__new__ 在实例创建之前被调用,负责返回一个实例对象。只有当 __new__ 方法返回一个实例对象时,__init__ 方法才会被调用。因此,如果我们需要控制实例的创建过程,可以重写 __new__ 方法。
class Animal:
def __new__(cls, name, age):
instance = super(Animal, cls).__new__(cls)
return instance
def __init__(self, name, age):
self.name = name
self.age = age
# 创建实例
dog = Animal("Buddy", 5)
print(dog.name) # 输出: Buddy
print(dog.age) # 输出: 5
在这个例子中,__new__ 方法创建了一个新的实例对象并返回,随后 __init__ 方法对这个实例进行初始化。
__new__ 和 __init__ 的关系
__new__是负责创建实例的,返回一个实例对象。__init__是负责初始化实例的,对创建好的实例进行属性设置。
可以这样理解:__new__ 是“制造工厂”,__init__ 是“装修工人”。
实际案例
1. 创建不可变对象
不可变对象在创建后其状态不能被修改。比如 Python 中的 int、str 等类型。我们可以通过重写 __new__ 方法来创建类似的不可变对象。
class ImmutablePoint:
def __new__(cls, x, y):
instance = super(ImmutablePoint, cls).__new__(cls)
instance._x = x
instance._y = y
return instance
@property
def x(self):
return self._x
@property
def y(self):
return self._y
point = ImmutablePoint(1, 2)
print(point.x) # 输出: 1
print(point.y) # 输出: 2
# 尝试修改属性
# point.x = 3 # 这行代码会报错
在这个例子中,ImmutablePoint 类通过重写 __new__ 方法和使用只读属性,创建了一个不可变的点对象。
2. 单例模式
单例模式保证一个类只有一个实例。我们可以通过重写 __new__ 方法来实现单例模式。
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance
def __init__(self, value):
self.value = value
singleton1 = Singleton(1)
singleton2 = Singleton(2)
print(singleton1.value) # 输出: 2
print(singleton2.value) # 输出: 2
print(singleton1 is singleton2) # 输出: True
在这个例子中,无论创建多少次 Singleton 类的实例,返回的都是同一个对象。
__init__用于初始化实例,设置实例属性。__new__用于创建实例,适合控制实例创建过程和处理不可变对象。
理解 __init__ 和 __new__ 是深入掌握 Python 面向对象编程的重要一步。希望本文能帮助你更好地理解这两个方法的区别和使用方法。
1495

被折叠的 条评论
为什么被折叠?



