2016-03-05 70 views
0

如果您想擴展一個類及其各自的__init__方法,是否有辦法處理大量的參數,包括新的參數?例如:如何擴展大類方法?

class Thing: 
    def __init__(self, arg1, arg2, arg3, arg4): 
     # Initialize 

class SubThing(Thing): 
    def __init__(self, arg1, arg2, arg3, arg4, ex_arg1, ex_arg2): 
     super().__init__(arg1, arg2, arg3, arg4): 
     # Do extra initialization 

是否有可能縮短的參數列表的子類的__init__方法?諸如this one之類的答案沒有描述如何向init中添加參數,或者如何處理額外的關鍵字參數,如__init__(self, arg1, arg_room='Bedroom', ex_arg1, ex_position=(0, 0), ex_arg2)

+1

簡答:不,沒有辦法做到這一點,而不寫出你想傳遞的所有參數。 – poke

+0

有* args和** kwargs,但我不認爲這正是你所要求的。 –

回答

0

有沒有真的偉大的辦法做你想做的。一般來說,命名所有參數是主要的方法。

雖然有幾種方法可能會有所幫助。一種是將一些參數捆綁到較大的集合中,因此您只需將一個項傳遞給父類,而不是幾個。以下是使用可迭代序列來保存arg1 - arg4的示例,但您可能需要改爲使用自定義類(請參閱csv模塊中的Dialect類,以獲取其他類型捆綁多個參數的類型示例) :

def __init__(self, thing_args, ex_arg1, ex_arg2): 
    super().__init__(*thing_args) 
    # ... 

另一種方式去是使用*args和/或**kwargs接收要傳遞沿參數。使用位置*args實在是太有限,因爲你必須列出你所關心的在子類中領先所有參數的參數你一起傳遞:

def __init__(self, ex_arg1, ex_arg2, *args): 
    super().__init__(*args) 
    # ... 

來電者首先需要列出值的ex_argsN paramters ,這可能是不自然的。越多的子類越變得越糟糕。

需要的一切傳遞作爲關鍵字參數可能會更好,因爲主叫方可以把任何順序似乎是最自然的關鍵字參數:

def __init__(self, *, ex_args1, ex_args2, **kwargs): 
    super.__init__(self, **kwargs) # passes along the unnamed keyword args 
    # ... 

最大的缺點這種方法是調用得到相當冗長與所有的參數名稱:

st = SubThing(arg1="foo", arg2="bar", arg3="baz", arg4="quux", 
       ex_arg1=1, ex_arg2=6.02e23) 
0

您可以做一些類似的引用的答案,除了刪除特定於您的子類的項目。

class Thing: 
    def __init__(self, arg1, arg2, arg3, arg4, kw1=None, kw2=None): 
     print('Thing args:',arg1,arg2,arg3,arg4) 
     print('Thing kw:',kw1,kw2) 

class SubThing(Thing): 
    def __init__(self, *args, **kw): 
     """SubThing(arg1, arg2, arg3, arg4, arg5, arg6, kw1=None, kw2=None, 
     kw3=None, kw4=None) 
     """ 
     if len(args) != 6: 
      raise TypeError(
       "SubThing() takes 6 positional arguments but {} were given" 
       .format(len(args))) 
     arg5, arg6 = args[4:] 
     kw3 = kw.pop('kw3', None) 
     kw4 = kw.pop('kw4', None) 
     super().__init__(*args[:4], **kw) 


SubThing(1,2,3,4,5,6,kw1='kw1',kw4='kw4') 
print('---- but populating kwargs from positional args stops working ----') 
Thing(1,2,3,4, 'kw1', 'kw2') 
SubThing(1,2,3,4,5,6,'kw1','kw2') 

這導致在第二個例子中

Thing args: 1 2 3 4 
Thing kw: kw1 None 
---- but populating kwargs from positional args stops working ---- 
Thing args: 1 2 3 4 
Thing kw: kw1 kw2 
Traceback (most recent call last): 
    File "n.py", line 24, in <module> 
    SubThing(1,2,3,4,5,6,'kw1','kw2') 
    File "n.py", line 14, in __init__ 
    .format(len(args))) 
TypeError: SubThing() takes 6 positional arguments but 8 were given 

注意,你失去了一些功能,因爲特別的位置參數並沒有在關鍵字參數自動填充。你可以用更多的編碼來解決這個問題,或者只是接受限制。許多使用*args, **kw的課程忘記了這麼做,以至於你的公司很好。