2016-09-08 9 views
1

これは期待通りに機能しますが、私はこのアプローチについて何らかの形で不確実です。それは安全ですか?それはpythonicですか?メソッドをプレーン関数で置き換えることはできますか?

class Example: 
    def __init__(self, parameter): 
     if parameter == 0: 
      # trivial case, the result is always zero 
      self.calc = lambda x: 0.0 # <== replacing a method 
     self._parameter = parameter 

    def calc(self, x): 
     # ... long calculation of result ... 
     return result 

(Python2とのpython3の間に違いがあれば、私は唯一のpython3を使用しています。)

+1

読み取り、デバッグする、すなわち困難醜いですが、それは動作します。 – zvone

+3

ちょっといいのは 'x:self.calc = self._calc else:self.calc = lambda ...'のようなものです。 – zvone

+2

これは特別な方法( '__xxx__')でない限り安全です個々のインスタンスではなく、オブジェクト(そのクラス)のタイプに基づいて常に検索されます。非常にPythonicではないので、適度に使用してください。 – martineau

答えて

3

あなたは問題がparameterこれまで変化しなければならないので、私はそれは良い習慣は考えていないでしょう。 は代わりに、私はあなたがこれを行うべきだと思う:これは非常に混乱して

class Example: 
    def __init__(self, parameter): 
     self._parameter = parameter 

    def calc(self, x): 
     if not self._parameter: 
      return 0.0 
     # ... long calculation of result ... 
     return result 
+0

私は受け入れる特定の答えを選ぶことはありませんので、それぞれの回答とコメントに良い点があるので、私はこれまでに得たことをお祈りください – VPfB

4

。他の誰かがそれを読むと、何が起こっているのか理解できません。メソッドの先頭にifステートメントを挿入するだけです。それは0で初期化された後、あなたがself.parameterを変更した場合

def calc(self, x): 
    if self.parameter == 0: 
     return 0 
    # ... long calculation of result ... 
    return result 

また、あなたの関数はもう動作しません。

+0

私は混乱に同意します。私は受け入れる特定の答えを選んでいないと言い訳をします。なぜなら、それぞれの答えとコメントに良い点があるからです。 – VPfB

0

私はいくつかのコメントと回答の概要を投稿することに決めました。この要約には投票しないでください。代わりにを元の著者に+1してください。

  • アプローチは、アプローチが
  • 等、unpythonic望ましくない、または不要とみなされる特別__methods__
  • を除いて使用する機能を決定するパラメータは一定でなければならない安全です。そうでない場合、このアプローチはまったく意味がありません。
  • 私は一般的な例については、以下のコードと簡単な例のための明白なif cond: return 0.0を好む、いくつかの提案から:

class Example: 
    def __init__(self, parameter): 
     if parameter == 0: 
      self.calc = self._calc_trivial 
     else: 
      # ... pre-compute data if necessary ... 
      self.calc = self._calc_regular 
     self._parameter = parameter 

    def _calc_regular(self, x): 
     # ... long calculation of result ... 
     return result 

    @staticmethod 
    def _calc_trivial(x): 
     return 0.0 
+0

これは本当に必要ではないため、Pythonではありません。実際、 '.calc'を呼び出すたびに' ._parameter'をテストするのではなく、これを行う方が少し効率的ですが、 '.calc_regular'自体が自明でない限り、相対的な速度差は小さいです。 IOWでは、この最適化により、コードの効率を最小限に向上させ、コードを読みやすく保守しやすくします。また、他の人が触れたように、 '._parameter'がインスタンスが作成された後に0からまたは0に変化すると、期待通りに動作しません。 –

+0

@ PM2Ring:_parameterを変更することができる場合、正しい関数を選択する全体のポイントは1回だけ失われます。要約を更新します。 – VPfB

+2

しかし、 '._parameter'の変更を実際に防ぐ方法はありません。 OTOHでは、属性名の先頭のアンダースコアは、このクラスを使用する人に、その属性を直接操作するコードが悪いアイデアであるとアドバイスします。 –

関連する問題