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

有没有办法绕过python中的类的构造函数__init__

例:

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

    def Print(self):
        print "YEHAA"

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

a = A
a.Print()

编辑:

一个更复杂的示例:

假设我有一个对象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实例,所以我必须以某种方式调用构造函数。

旧编辑:

一个更复杂的示例,它解释了为什么我要问:

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__。当然,我可以简单地存储它,但是如果数据是一个巨大的对象,而我又不想一直将其存储在内存中甚至将其保存到磁盘上怎么办?

参考方案

您可以通过直接调用__init__来规避__new__。然后,您可以创建给定类型的对象,并为__init__调用替代方法。这是pickle会做的。

但是,首先我要特别强调的是,您不应该这样做,不管您想要实现什么,都有更好的方法来实现,其中一些已在其他答案中提到。特别是,跳过调用__init__是一个坏主意。

创建对象时,或多或少会发生这种情况:

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

您可以跳过第二步。

这就是为什么您不应该这样做: __init__的目的是初始化对象,填写所有字段并确保还调用父类的__init__方法。使用pickle是一个例外,因为它会尝试存储与该对象关联的所有数据(包括为该对象设置的任何字段/实例变量),因此上次__init__设置的任何内容都会被pickle恢复,无需再次调用。

如果跳过__init__并使用替代的初始化程序,则会有某种形式的代码重复-实例变量将在两个地方填充,很容易在其中一个初始化程序中遗漏其中一个,或者不小心使它们这两个填充字段的行为不同。这样就可以发现难以跟踪的细微错误(您必须知道调用了哪个初始化程序),并且代码将更难以维护。更不用说如果您使用继承会陷入更大的混乱-问题将在继承链中蔓延,因为您必须在链的各处使用此替代初始化器。

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

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

  • 支持__init__的不同签名,这些签名通过使用可选参数来处理您的情况。
  • 创建几个用作替代构造函数的类方法。确保它们都以正常方式(即调用__init__),as shown by Roman Bodnarchuk创建类的实例,同时执行其他工作或执行其他操作。最好是将所有数据传递给类(并由__init__处理),但是,如果这不可能或不方便,则可以在创建实例并完成__init__之后设置一些实例变量。
  • 如果__init__具有可选步骤(例如,像处理该data参数一样,尽管您必须更具体一点),则可以将其设为可选参数,或者使之成为执行该处理的常规方法...或同时进行。

    如何重写在__init__.py中定义的方法? - python

    我正在尝试使用模块(pandas_access),在__init__.py上定义的方法(_extract_dtype)上有问题覆盖__init__.py上定义的方法的正确方法(或任何方法)是什么? 参考方案 您可以“猴子补丁”方法,例如def _extract_dtype_patched(self): print("Patched version&…

    如何根据传递给__init__方法的字符串值在类内命名变量? - python

                                    class MyClass: __init__(self, some_string): self.some_string = anything 因此类似于pandas的DataFrame类,在该类中,可以通过在点运算符后面附加列名来引用列。喜欢:df.column_name_of_some_co…

    python类中的变量范围 - python

    在类中声明变量(在函数外部):所有类函数都可以访问它(基本上是公共变量)在类内的函数内声明变量:只有该函数才能访问它(在该函数范围内)在类内的函数内部声明带有self。(变量名)的变量:所有类函数都可以访问它(这与全局变量名有何不同?)并且由于没有私有/受保护的事物,所以所有事物都是公共的,因此可以从类外部访问所有从类内部访问的事物。我还有其他细微差别应该知…

    Python GPU资源利用 - python

    我有一个Python脚本在某些深度学习模型上运行推理。有什么办法可以找出GPU资源的利用率水平?例如,使用着色器,float16乘法器等。我似乎在网上找不到太多有关这些GPU资源的文档。谢谢! 参考方案 您可以尝试在像Renderdoc这样的GPU分析器中运行pyxthon应用程序。它将分析您的跑步情况。您将能够获得有关已使用资源,已用缓冲区,不同渲染状态上…

    Python:图像处理可产生皱纹纸效果 - python

    也许很难描述我的问题。我正在寻找Python中的算法,以在带有某些文本的白色图像上创建皱纹纸效果。我的第一个尝试是在带有文字的图像上添加一些真实的皱纹纸图像(具有透明度)。看起来不错,但副作用是文本没有真正起皱。所以我正在寻找更好的解决方案,有什么想法吗?谢谢 参考方案 除了使用透明性之外,假设您有两张相同尺寸的图像,一张在皱纹纸上明亮,一张在白色背景上有深…