【问题标题】:python: error when running __new__? not invoking __init__python:运行__new__时出错?不调用 __init__
【发布时间】:2021-03-23 19:42:15
【问题描述】:

我正在阅读有关 __new____init__ 的继承和使用的 Python 文档

https://docs.python.org/3/reference/datamodel.html#basic-customization

我正在尝试创建一个类“config”,它将是一个通用类,其中包含我所有项目共有的所有基本方法

from abc import ABCMeta, abstractmethod

class MyConfig(metaclass=ABCMeta):
    def __new__(cls, *args, **kwargs):
        print("Config new")
        return cls

    def __init__(self):
        print("Config init")

然后,当我创建一个新项目时,我将导入该通用 config 类并为该项目创建一个特定的配置类

# from config import MyConfig

class MyConfiguration(MyConfig):
    def __init__(self, *args, **kwargs):
        super(MyConfiguration, self).__init__(*args, **kwargs)
        print("Configuration init")

当我实例化我的配置时,我会指定 __new____init__ 方法运行,但只运行 __new__

c = MyConfiguration()

这是输出:

Config new

文档说:

如果在对象构造期间调用__new__(),它返回一个实例或cls的子类,那么新实例的__init__()方法将像__init__(self[, ...])一样被调用,其中self是新实例,其余参数是与传递给对象构造函数的相同。

如果__new__()没有返回cls的实例,那么新实例的__init__()方法将不会被调用。

由于只有__new__ 方法的输出,这意味着我做错了,因为__init__ 方法没有被调用。

欢迎任何帮助。

【问题讨论】:

  • __init__() 只有在您的 __new__() 返回可以有效调用的内容时才会调用 - 即类的实例。您正在返回课程本身。
  • 谢谢。我想我没有完全理解 new 应该返回什么。
  • 更准确地说,__init__ 仅在__new__ 返回cls(的子类)的实例时调用

标签: python new-operator init


【解决方案1】:

__init__() 只会在您的 __new__() 返回可以有效调用的内容时调用 - 即类的实例。

在您的示例中,您返回的是类本身。

这是您可以做到的一种方法: 创建类的实例,并返回它而不是返回类本身:

from abc import ABCMeta, abstractmethod

class MyConfig(metaclass=ABCMeta):
      def __new__(cls, *args, **kwargs):
            instance = super(MyConfig, cls).__new__(cls, *args, **kwargs)
            print("Config new")
            return instance
      
      def __init__(self, *args, **kwargs):
            print("Config init")

class MyConfiguration(MyConfig):
      def __init__(self, *args, **kwargs):
            super(MyConfiguration, self).__init__(*args, **kwargs)
            print("Configuration init")
        
if __name__ == '__main__':
      c = MyConfiguration()

输出:

Config new
Config init
Configuration init

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-09
    • 2011-06-19
    • 2014-03-01
    • 2015-12-09
    • 2019-09-13
    • 2019-02-06
    • 2017-03-25
    • 1970-01-01
    相关资源
    最近更新 更多