1

我使用拷貝構造函數尋找一種方法來初始化派生類和()運算符類似於C++的Python:多重繼承,拷貝構造函數,類的初始化和()超載

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*/ 

,然後我就在想我將如何實現intitialisation的情況下,這種方式我已經從自己的另外兩個多名會員和派生類想出瞭如下:

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的方式?如果有更好的方法(或者無法做到這一點)?

+0

在Python中,您將定義一個'__copy__'和'__deepcopy__'特殊方法,用於'copy.copy'和'copy.deepcopy'函數。 –

+0

例如,請參見[此問題](http://stackoverflow.com/questions/15684881/python-implementation-of-shallow-and-deep-copy-constructors) –

回答

1

那麼,你不想創建一個實例來創建一個新的實例,所以你可能需要一個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) 

但在使用和基礎1的和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) 

在蟒蛇少「聰明」經常「更好」

+0

謝謝!我在草稿中用@classmethod實現了,只是確實試圖用()運算符做「聰明」,我清楚地看到它是不好的。 –