Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何将构造函数方法传递给另一个方法并在那里调用它?_Python_Inheritance_Methods - Fatal编程技术网

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

Python 如何将构造函数方法传递给另一个方法并在那里调用它?,python,inheritance,methods,Python,Inheritance,Methods,我试图避免在两个类的克隆方法中重复相同的代码,一个从另一个继承。我目前的方法是将两个类共有的代码放在基类的(非静态)克隆方法中,并从扩展类调用它。为此,我试图将扩展类的构造函数传递给基类,以便在基类中调用它。以下是我目前正在做的一个简化示例: class S(object): """Base class""" def __init__(self): self.a = 0 def clone(self, constructor=None):

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

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()
在这一点上,我的问题是:

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

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

  • 你有什么更好的建议吗

虽然在Python中,
\uuu init\uuu()
通常被称为构造函数,但实际上不是。它获取作为
self
参数传入的实例,并返回
None
。该实例在前面由
\uuuuu new\uuuu()
方法构造,该方法是实际的构造函数。不过,您不应该传入对
\uuuu new\uuu
的引用。传入类型本身更容易、更直接


Edit:实现
clone
方法的正确方法是另一种方法:坚持通常的Python协议,在实例上实现and。然后,您可以使用
copy
模块中的函数正确克隆实例。

您的基类克隆方法是多余的。从任何上下文调用
self.\uuuu init\uuu()
都将遵循对象特定实例的MRO,这意味着在
C
的实例上调用
clone()
将从
S
中的代码调用
C.\uu init\uuuuu()
,而无需明确指定使用
C.\uu init\uuuu()

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


另外,特别是对于
clone()
类型操作,您可能需要查看重载
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
而不是实施一个新的辩证元素。

你知道
复制
模块吗?@KarlKnechtel:是的,但我做了一些错误的假设,使我认为它不足以满足我所要做的。事实证明是这样的。在其他语言中,构造函数也在已分配内存和已构造但未初始化对象的上下文中运行。在
\uuuu init\uuuu
中,它不是构造函数到底有什么不同?O_o@BartoszKP这个问题的主旨是希望构造函数生成一个新的对象并返回它,但它没有,我的回答是要说明这一点。也就是说,在C++中,代码的作用肯定有差异。最重要的区别是,
\uuuu new\uuu()
已经以一致的状态返回一个完全工作的对象,在某些情况下甚至是一个初始化的对象(例如,对于不可变类型) >代码>比C++中的分配器要重要得多,这就是为什么我把它称为“实际”构造函数的原因。对象是否“完全工作”取决于代码< >代码>第i个ITITY < /COD>和基类,它可以与C++中的VTABLE(您可能已经想到的)完全一样的类型的设置。例如,它应该从子类显式地调用base的
\uuuuu init\uuuuu
,因此在这种情况下我不会称它为“完全工作”。@BartoszKP我不会坚持使用这个术语-调用
\uuuuu init\uuuuuuu()
构造函数和
\uuuuu new\uuuuuuuuu()
构造函数都是合理的。这个答案中的措辞可能过于强硬,但我并不在意——我主要是想回答老年退休金计划的问题。你是对的,我承认这是一个区别(不是很大,但值得一提)。而且,这正是文档所说的(这两个函数一起作为构造函数工作):)干杯!