2016-05-22 67 views
1

我想定義一個函數,它的父類會返回一個父類可以接收和使用的值。雖然我認爲可以通過元類實現這一點,但我不確定如何做(假設可能)以及是否有更好,更乾淨的解決方案。如何在不覆蓋父函數的情況下將值返回給超類?

我想要的格式如下所示。 Child類將由除我以外的開發人員定義,因此我希望儘可能少地限制。 (例如,我最好不要使用super(Child).f(a)來替換return a。)我也不確定如何使用關鍵字參數與我的模型,這將是更可取的。

class Parent: 
    def f(self, arg): 
     print("Received {}.".format(arg)) 
     return arg ** 3 

class Child(Parent): 
    def f(self, c, b, a): 
     print(a, b, c) 
     return a 

# Prints "2 1 0" and "Received 2.". Sets value to 8. 
value = Child().f(0, 1, 2) 
+0

打印'2 1 0'有關python 2.7和3.4 – csl

+1

如果定義在具有相同名稱的子類中的方法,然後通過定義你覆蓋父方法。我很確定你想做什麼是不可能的,無論如何也不是一個好主意。我建議你在父調用'f'中有一些抽象方法'g',孩子負責覆寫。 –

+0

注意它只是'return super().f(a)'。 – jonrsharpe

回答

3

沒有與此聲明的一個關鍵問題:

我想定義一個函數具有相同的名稱爲其父返回一個值,家長可以收到

請問,爲什麼這是必要的?

Child類中的f與Parent類中的f完全不同,因此將它們命名爲相同的東西,即使讓它起作用也是非常混亂的。

可以說,我用寫的子類的Parent

class Child(Parent): 
    def f(self): 
     return 2 

我希望Child().f()返回2,但是,如果要添加,增加了arg ** 3幕後隱藏的邏輯那我反而會得到8完全混淆並詛咒你的圖書館添加非直觀的規則。


而是爲什麼沒有被使用的一個功能,並在子類中定義了額外的邏輯輔助函數:

class Parent: 
    def f(self, *v_args): 
     arg = self.helper_f(*v_args) 
     print("Received {}.".format(arg)) 
     return arg ** 3 

    def helper_f(self,*args): 
     "really should be an abstract method, must be implemented in a subclass" 
     raise NotImplementedError("Must override in a subclass!") 

class Child(Parent): 
    def helper_f(self, c, b, a): 
     print(a, b, c) 
     return a 

# Prints "Received 2.". Sets value to 8. 
value = Child().f(0, 1, 2) 

當然,是的,你在技術上可以與元類自動化此。但同樣,這使用Parent

class Child_Method_Redirector(type): 
    def __new__(meta, name, bases, cls_dict): 
     if bases is not(): 
      if "f" in cls_dict: 
       cls_dict["_auto_renamed_helper_f"] = cls_dict["f"] 
       del cls_dict["f"] 
     return type.__new__(meta,name,bases,cls_dict) 


class Parent(metaclass=Child_Method_Redirector): 
    def f(self, *v_args): 
     arg = self._auto_renamed_helper_f(*v_args) 
     print("Received {}.".format(arg)) 
     return arg ** 3 

class Child(Parent): 
    def f(self): 
     return 2 

# now it does Print "Received 2." and Sets value to 8. 
value = Child().f() 

請不要這樣做完全混亂給任何人,它違背the zen

明確優於隱式。
應該有一個 - 最好只有一個 - 明顯的方法來做到這一點。
如果實施難以解釋,這是一個壞主意。

+1

作爲一個附註我想指出,「可以實現一個特殊的方法,在<...>條件下調用」是相當普遍的方法,只是想到一個'dict'子類覆蓋'__missing__' –

相關問題