【问题标题】:Instantiate children class from parent without changing parent code从父类实例化子类而不更改父代码
【发布时间】:2013-05-07 04:51:41
【问题描述】:

首先,这是我的(伪)代码:

somemodule.py:

class parentclass(object):
    def __init__(self):
        if(not prevent_infinite_reursion) #Just to make shure this is not a problem ;)
            self.somefunction()

    def somefunction():

        # ... deep down in a function ...

        # I want to "monkey patch" to call constructor of childclass, 
        # not parentclass
        parentclass() 

其他模块.py

from somemodule import parentclass

class childclass(parentclass):
    def __init__(self):
        # ... some preprocessing ...

        super(childclass, self).__init__()

问题是,我想修改父类,所以它会调用 childclass 的构造函数,而不更改 somemodule.py 的代码。 是否仅在类实例中修补(这更好)或全局修补都没有关系。

我知道我可以重写 somefunction,但它包含太多代码行,因为这是理智的。

谢谢!

【问题讨论】:

  • 您希望 所有 尝试构造 parentclass 来代替构造 childclass,或仅在 parentclass 内尝试,或仅在 parentclass.somefunction 内进行此特定尝试, 或后两者之一,但仅当 selfchildclass?
  • 所有这些,所以我会很感激任何答案,但最好是在父类中尝试。
  • 其实,这可能是最困难的可能性。但是让我想想……
  • 我在my very first answer on StackOverflow 中介绍了这一点,尽管它替换了parentclass()所有 次出现。
  • 我能想到两个可能会起作用的骇人听闻的事情:(1) 将parentclass 的每个方法替换为修补__new__、调用原始文件并恢复__new__ 的包装器。 (2) 将parentclass 的每个方法替换为在修改后的globals 中运行原始的包装器,其中parentclass 已被childclass 替换。但我认为这些都不是一个值得编码的好主意。

标签: python class inheritance instantiation


【解决方案1】:

您可以为此使用mock.patch

class childclass(parentclass):
    def somefunction(self):
        with patch('somemodule.parentclass', childclass):
            super(childclass, self).somefunction()

【讨论】:

  • 一个很好的干净的方式来做我的“可怕的 hacky 事情 (1)”。
  • 嗯,在我的情况下它不起作用,因为父类最终是某个其他类的子类,并且父类 new 方法的父类被调用,它创建父类而不是假设修补子类,将尝试找到如何管理它。
  • @offlinehacker 您也可以修补__new__ 方法。阅读where to patch也可能会有所帮助。
  • @LauritzV.Thaulow 最终它就像一个魅力一样修补了顶级的__new__。这个很难。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-21
  • 2023-03-30
  • 2021-08-28
  • 2014-04-04
  • 1970-01-01
相关资源
最近更新 更多