网站背景素材南宁网站建设服务公司
1. Python 类的 __new__
方法
在 Python 中,__new__
是一个静态方法,负责创建类的实例。
- 默认行为:当定义一个类时,若未显式定义
__new__
方法,Python 会自动调用父类(通常是object
)的__new__
方法创建实例。 - 关键作用:
__new__
返回实例后,__init__
方法才会被调用以初始化实例。
2. super()
的行为解析
super()
函数用于调用父类(超类)的方法。- 在类的上下文中,
super()
会根据当前类的 方法解析顺序(MRO) 查找下一个父类。
示例代码:
class MyClass:def __new__(cls, *args, **kwargs):print("MyClass __new__ called")return super().__new__(cls) # 调用父类的 __new__ 方法obj = MyClass()
运行结果:
MyClass __new__ called
解析:
MyClass
没有显式继承其他类,因此默认父类是object
。super().__new__(cls)
等价于object.__new__(cls)
,即调用object
的__new__
方法创建实例。
3. 单例模式中的 __new__
方法覆盖
在单例模式中,我们需要覆盖 __new__
方法,以确保只创建一个实例。
示例代码:
class SingletonLogger:_instance = None # 保存唯一实例def __new__(cls, *args, **kwargs):if not cls._instance:# 调用父类的 __new__ 方法创建实例cls._instance = super().__new__(cls)cls._instance.init_logger() # 初始化日志配置return cls._instancedef init_logger(self):import loggingself.logger = logging.getLogger("SingletonLogger")self.logger.setLevel(logging.INFO)handler = logging.StreamHandler()self.logger.addHandler(handler)def info(self, message):self.logger.info(message)
关键点:
super().__new__(cls)
调用的是object.__new__(cls)
,因为SingletonLogger
的父类是object
。- 这一步实际完成了实例的物理创建(分配内存等操作)。
4. 为什么必须调用 super().__new__(cls)
?
- 实例的物理创建:Python 中对象的创建(内存分配)必须由
__new__
方法完成。 - 不调用父类
__new__
的后果:若在__new__
中不调用父类的方法,将无法生成有效的实例。例如:class BadSingleton:_instance = Nonedef __new__(cls):if not cls._instance:# 错误!没有调用父类的 __new__,直接返回一个无效实例cls._instance = object.__new__(cls)return cls._instance
- 此处
object.__new__(cls)
正确,但若完全忽略父类方法,会导致未定义行为。
- 此处
5. 对比元类实现与 __new__
覆盖实现
元类实现单例
class Singleton(type):def __call__(cls, *args, **kwargs):if not cls.instance:cls.instance = super().__call__(*args, **kwargs)return cls.instanceclass MyClass(metaclass=Singleton):pass
- 原理:通过元类的
__call__
方法拦截实例化请求,控制实例创建。 - 调用链:
MyClass()
→Singleton.__call__()
→type.__call__()
(实际创建实例)。
覆盖 __new__
方法实现单例
class SingletonClass:_instance = Nonedef __new__(cls, *args, **kwargs):if not cls._instance:cls._instance = super().__new__(cls)return cls._instance
- 原理:在类的
__new__
方法中控制实例创建,直接返回已有实例。 - 调用链:
SingletonClass()
→SingletonClass.__new__()
→object.__new__()
。
6. 验证 super()
的父类指向
通过打印 super()
的信息,可以明确其指向的父类:
class Parent:passclass Child(Parent):def __new__(cls, *args, **kwargs):print("Child __new__ called")print("super() in Child:", super())return super().__new__(cls)obj = Child()
输出:
Child __new__ called
super() in Child: <super: <class 'Child'>, <Child object>>
解析:
super()
在Child
类中指向的是Parent
类(因为Child
显式继承自Parent
)。- 若类没有显式继承,默认指向
object
。
总结
super().__new__(cls)
的作用:调用父类的__new__
方法完成实例的物理创建。- 父类的指向:
- 若类显式继承自某个父类(如
class MyClass(Parent)
),则super()
指向该父类。 - 若类没有显式继承(如
class MyClass
),则super()
默认指向object
。
- 若类显式继承自某个父类(如
- 单例模式的核心:无论通过元类还是覆盖
__new__
方法,核心逻辑都是控制实例的创建次数,确保全局唯一性。