有没有一种方法可以在不调用 __init__ 的情况下实例化一个类?

2023-12-01

有没有办法绕过构造函数__init__python 中的一个类?

Example:

class A(object):    
    def __init__(self):
        print "FAILURE"

    def Print(self):
        print "YEHAA"

现在我想创建一个实例A。它可能看起来像这样,但这种语法不正确。

a = A
a.Print()

EDIT:

一个更复杂的例子:

假设我有一个对象C,其目的是存储一个参数并用它进行一些计算。然而,参数并不是这样传递的,而是嵌入在一个巨大的参数文件中。它可能看起来像这样:

class C(object):
    def __init__(self, ParameterFile):
        self._Parameter = self._ExtractParamterFile(ParameterFile)
    def _ExtractParamterFile(self, ParameterFile):
        #does some complex magic to extract the right parameter
        return the_extracted_parameter

现在我想转储并加载该对象的实例C。但是,当我加载这个对象时,我只有单个变量self._Parameter我无法调用构造函数,因为它需要参数文件。

    @staticmethod
    def Load(file):
        f = open(file, "rb")
        oldObject = pickle.load(f)
        f.close()

        #somehow create newObject without calling __init__
        newObject._Parameter = oldObject._Parameter
        return newObject

也就是说,不传递参数文件就无法创建实例。然而,在我的“真实”情况下,它不是一个参数文件,而是一些巨大的数据垃圾,我当然不想在内存中携带,甚至将其存储到光盘上。

因为我想返回一个实例C从方法Load我确实必须调用构造函数。

旧编辑:

一个更复杂的例子,解释了why我问的问题是:

class B(object):    
    def __init__(self, name, data):
        self._Name = name
        #do something with data, but do NOT save data in a variable

    @staticmethod
    def Load(self, file, newName):
        f = open(file, "rb")
        s = pickle.load(f)
        f.close()

        newS = B(???)
        newS._Name = newName
        return newS

正如你所看到的,自从data未存储在类变量中,我无法将其传递给__init__。当然,我可以简单地存储它,但是如果数据是一个巨大的对象,我不想一直在内存中携带它,甚至不想将其保存到磁盘上怎么办?


You can规避__init__通过致电__new__直接地。然后您可以创建给定类型的对象并调用替代方法__init__。这是一个东西pickle会做。

然而,首先我想强调的是,这是你不应该无论您想要实现什么目标,都有更好的方法来实现,其中一些方法已在其他答案中提到。特别是,它是一个bad跳过通话的想法__init__.

创建对象时,或多或少会发生以下情况:

a = A.__new__(A, *args, **kwargs)
a.__init__(*args, **kwargs)

您可以跳过第二步。

这就是为什么你不应该做这个:的目的__init__是初始化对象,填充所有字段并确保__init__父类的方法也会被调用。和pickle它是一个例外,因为它尝试存储与该对象关联的所有数据(包括any为对象设置的字段/实例变量),以及由__init__之前的时间会被pickle恢复,不需要再次调用。

如果你跳过__init__并使用替代的初始化程序,您将有一种代码重复 - 将会有两个地方填充实例变量,并且很容易在其中一个初始化程序中错过其中一个,或者意外地使两个地方填充字段的行为有所不同。这可能会出现一些微妙的错误,这些错误并不是那么容易追踪的(你必须know调用了哪个初始化程序),并且代码将更加难以维护。更不用说,如果您使用继承,您会陷入更大的混乱 - 问题将沿着继承链上升,因为您必须在链上的任何地方使用这个替代初始化程序。

另外,通过这样做,您或多或少会覆盖 Python 的实例创建并创建您自己的实例。 Python 已经很好地为你做到了这一点,无需重新发明它,它会让使用你的代码的人感到困惑。

以下是最好的做法:使用单个__init__为正确初始化所有实例变量的类的所有可能实例化调用的方法。对于不同的初始化模式,请使用以下两种方法之一:

  1. 支持不同的签名__init__通过使用可选参数来处理您的情况。
  2. 创建几个用作替代构造函数的类方法。确保它们都以正常方式创建类的实例(即调用__init__), 如罗曼·博德纳丘克所示,同时执行额外的工作或其他工作。最好是他们将所有数据传递给班级(并且__init__处理它),但如果这是不可能或不方便的,您可以在创建实例后设置一些实例变量,__init__初始化完成。

If __init__有一个可选步骤(例如,像处理data参数,尽管您必须更具体),您可以将其作为可选参数或创建一个执行处理的普通方法...或两者兼而有之。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有没有一种方法可以在不调用 __init__ 的情况下实例化一个类? 的相关文章

随机推荐