我正在寻找一种使用复制构造函数和 (( 运算符初始化派生类的方法,就像在 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 的方式?如果有更好的方法(或没有方法(来做同样的事情?
好吧,您不想创建一个实例来创建新实例,因此,您可能需要一个classmethod
或staticmethod
。这里也不是使用__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中,"聪明"往往"更好">