2016-05-22 3 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

python 2.7と3.4で '2 1 0'を表示 – csl

+1

同じ名前のサブクラスでメソッドを定義すると、定義によって親メソッドがオーバーライドされます。私はあなたがしたいことは不可能で、とにかく悪いアイデアになるだろうと確信しています。私はあなたが親コールに 'f'を持っていることをお勧めします。これは子がオーバーライドの責任を負う抽象メソッド' g'です。 –

+0

'super()。f(a)'だけであることに注意してください。 – jonrsharpe

答えて

3

この文を使用して、重要な問題があります:

私は親が

を受け取ることができるという値を返しますその親と同じ名前の関数 を定義したいと思います

質問してもよろしいですが、なぜこれが必要ですか?

子クラスのfはParentクラスのfとは全く異なります。そのため、同じ名前を付けても動作しても非常に混乱します。

私はあなたのParentを使用して、子クラスを書いたとしましょう:私はChild().f()は2を返すことを期待する

class Child(Parent): 
    def f(self): 
     return 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) 

を、はい、あなたが技術的にメタクラスでこれを自動化することができます。しかし、再び、これはそれがthe zen

明示的、暗黙的よりも優れているに反し、

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() 

しかしこのをしないてくださいParentクラスを使用して誰にも完全に混乱することでしょう。
これを実行するには、1つ、好ましくは1つの唯一の方法が必要です。
実装を説明するのが難しい場合は、悪い考えです。

+1

を参考にしてください。「<...> curcumstancesの下にある特別なメソッドを実装することができます」ということは、かなり一般的なものです。単に 'dict'サブクラスの' __missing__'をオーバーライドすると思います。 –

関連する問題