如何将构造函数方法传递给另一个方法并在那里调用它?

时间:2012-07-23 13:36:28

标签: python inheritance methods

我试图避免在两个类的克隆方法中重复相同的代码,一个继承自另一个类。我目前的方法是将两个类共有的代码放在基类的(非静态)克隆方法中,并从扩展类中调用它。为此,我试图将扩展类的构造函数传递给基类,以便可以在那里调用它。以下是我目前正在做的简化示例:

class S(object):
    """Base class"""
    def __init__(self):
        self.a = 0

    def clone(self, constructor=None):
        if constructor is None:
            constructor = self.__init__
        cloned = constructor()
        # Expecting: cloned.a = 1, cloned.b = 7

        assert cloned is not None  # raises AssertionError
        cloned.a = self.a  # Set a to 2
        return cloned

class C(S):
    """Child class, extending Base"""
    def __init__(self):
        self.a = 1
        self.b = 7

    def clone(self):
        cloned = super(C, self).clone(self.__init__)
        # Expecting: cloned.a = 2, cloned.b = 7

        cloned.b = self.b  # Set b to 8
        return cloned

if __name__ == '__main__':
    c1 = C()
    c1.a = 2
    c1.a = 8
    c2 = c1.clone()

我现在的问题是:

  • 为什么在调用基类的None方法时会返回clone

  • 我是否必须将方法绑定到类才能使用它 types.MethodType__get__

  • 您认为哪种方式更好?

2 个答案:

答案 0 :(得分:5)

虽然__init__()通常被称为Python中的构造函数,但它实际上并不是。它将实例作为self参数传入,并返回None。该实例之前由__new__()方法构造,该方法是实际的构造函数。但是,您不应该传递对__new__的引用。传递类型本身更容易,更直接。

编辑:实现clone方法的正确方法是另一种方法:坚持通常的Python协议,并实施__getstate__()__setstate__()你的实例。然后,您可以使用copy模块中的函数正确克隆实例。

答案 1 :(得分:2)

您的基类克隆方法是多余的。从任何上下文调用self.__init__()将遵循对象的特定实例中的MRO,这意味着在clone()的实例上调用C将从C.__init__()中的代码调用S {1}}未指定明确使用c.__init__()

如果您想要做的是能够自定义clone()而不必创建一个全新的类,或者根据其他因素有不同的行为,我建议您查看工厂/构建器模式。 / p>

此外,专门针对clone()类型的操作,您可能希望查看重载__copy__()__getstate__()__setstate__()并使用copy.copy()和{ {1}}而不是实现新的辩证元素。