Python:多重继承、复制构造函数、类初始化和()重载

标签 python multiple-inheritance copy-constructor in-class-initialization

我正在寻找一种像 C++ 中那样使用复制构造函数和 () 运算符来初始化派生类的方法

class Rectangle {
    int width, height;
  public:
    Rectangle (int,int);
    int area () {return (width*height);}
};

Rectangle::Rectangle (int a, int b) {
  width = a;
  height = b;
}

r = Rectangle(2,3)
s = Rectangle(r) /* <--using copy constructor to initialize*/

然后我在想,如果我有一个从其他两个成员派生的类,我将如何实现这种初始化方式,并提出了以下内容:

class MyBase1(object):
    def __init__(self, *args, **kwargs):
        self.x = kwargs.get('x')
        self.y = kwargs.get('y')
        print("mybase1 {}".format(kwargs))

    def print_base1(self):
        pass


class MyBase2(object):
    def __init__(self, *args, **kwargs):
        self.s = kwargs.get('s')
        self.p = kwargs.get('p')
        print("mybase2 {}".format(kwargs))

    def print_base2(self):
        pass


class MyChild(MyBase1, MyBase2):

    def __init__(self, **kwargs):
        MyBase1.__init__(self, **kwargs)
        MyBase2.__init__(self, **kwargs)
        self.function_name = kwargs.get('function')


    def __call__(self, my_base1, my_base2, **kwargs):
        initialization_dictionary = dict(vars(my_base1), **vars(my_base2))
        initialization_dictionary = dict(initialization_dictionary, **kwargs)
        newInstance = MyChild(**initialization_dictionary)
        return newInstance

然后调用:

base1 = MyBase1(x=1, y=2)
base2 = MyBase2(s=3, p=4)

child = MyChild()(base1, base2, function='arcsine') #<--initialising 

[stm for stm in dir(child) if not stm.startswith('__')]
# gives:['function_name', 'p', 'print_base1', 'print_base2', 's', 'x', 'y']

vars(child)
# gives:{'function_name': 'arcsine', 'p': 4, 's': 3, 'x': 1, 'y': 2}

所以我想知道这在多大程度上是非Pythonic的方式?如果有更好的方法(或没有方法)来做同样的事情?

最佳答案

好吧,您不想创建一个实例来创建一个新实例,因此您可能需要一个 classmethodstaticmethod。这也不是使用 __call__ 的地方。

我可能会这样做:

class MyChild(MyBase1, MyBase2):
    @classmethod
    def build_from_bases(klass, base1, base2, **kwargs):
        kwargs.update(base1.__dict__)
        # Note if base2 has values for x and y, they will clobber what was in base1
        kwargs.update(base2.__dict__)
        return klass(**kwargs)

但是使用 Base1 和 Base2 的实例来构建 MyChild 的实例并不像我在 python 中所做的那样。更有可能使用明显的:

mychild = MyChild(x=base1.x, y=base1.y, s=base2.s, p=base2.p, function='foo')

真的,我更喜欢这样,现在我不必担心破坏值或其他奇怪的事情。

如果你确实想要捷径方法,你可以将两者结合起来:

class MyChild(MyBase1, MyBase2):
    @classmethod
    def build_from_bases(klass, base1, base2, **kwargs):
       return klass(x=base1.x, y=base1.y, s=base2.s, p=base2.p, **kwargs)

在Python中,越“聪明”往往“越好”

关于Python:多重继承、复制构造函数、类初始化和()重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43057218/

相关文章:

python - 将 Cython 指向 C 源文件

c++ - 使用继承时是否需要 "#include"子类父类的头文件。 C++

c++ - 复杂的菱形继承(钻石问题) : C++ virtual inheritance

c++ - 析构函数导致程序崩溃

Python 检查 9*9 矩阵中的 3*3 矩阵是否重复,如数独

python - 如何替换文本 block 中的多个正则表达式匹配

python - 将 float 转换为 IEEE754

c++ - 将 void* 转换为多个继承类的父类(super class)不会调用正确的方法

c++ - Vector of pointer to objects,需要vector的深拷贝,但是对象是继承对象的基础

链接构造函数时的 Java 空参数