2017-11-26 14 views
-2

以下は私が作成したシンプルなクラスです。私はpreprocessが関数であるので、このような呼び出しが動作しないことが明らかであるpythonクラス:内部関数;ネストされた点を介してアクセスします

obj = TestClass().TestClass(data) 
obj.preprocess.gradient() 

のような内部機能にアクセスしたいと思います。どのように私が望むものを達成することができますか(私はあなたにはそれがはっきりしていることを望みます)

編集:これは単純なケースです。私は、機械学習に参加していない他のユーザーが、適切な関数を正しい順序で適用する方が簡単であることを願っています(最初は前処理、次にクラスタリング、その後のプロット)。私はちょうどそれがうまく動作する外部関数(前処理など)を削除しました。しかし、私はそのようなアプローチが合理的かもしれないと思う。

import numpy as np 
from sklearn.preprocessing import StandardScaler 

class TestClass: 

    def __init__(self, data): 
     self.data = data 
     self._preprocessed = data 

    # should not be a function but rather a "chapter" which 
    # separates preprocessing from analysis method 
    def preprocessing(self): 

     def gradient(self): 
      self._preprocessed = np.gradient(self._preprocessed, 2)[1] 

     def normalize(self): 
      self._preprocessed = StandardScaler().fit_transform(self._preprocessed) 

    def cluster_analysis(self): 

     def pca(self): 
      pass 
+1

私はあなたが 'obj = TestClass(data)'を意味すると思いますか?また、 'preprocess'メソッドはどこから来たのですか?代わりに' preprocessing'を意味しませんか?さらに、質問を定式化することが私たちを助けると思う。 – Kanak

+0

この問題の代表者は、あなたが解決しようとしている問題、または単純化した問題の代表者ですか?なぜなら、このメソッドが他の関数を定義できるだけであれば、これを実現するより良い方法があるからです。 – Reti43

+1

'gradient'は' preprocess'の戻り値の属性ではありません。 'preprocess'のスコープ内のローカル変数にすぎません。 'preprocess'は' gradient'属性を持つものを返す必要があります。あるいは、 'preprocess'はインスタンスメソッドではなく、単純なインスタンス属性である必要があります。 – chepner

答えて

0

(以下の第二のものよりおそらく良い)第1のアプローチは、このようにして組成物を有利には、これら2つのメソッドを有するクラスのインスタンスを返すようになるであろう。

#... 
    @property 
    def preprocessing(self): 

     def gradient(self): 
      self._preprocessed = np.gradient(self._preprocessed, 2)[1] 

     def normalize(self): 
      self._preprocessed = StandardScaler().fit_transform(self._preprocessed) 

     callables_dict = { 
      'gradient':gradient, 
      'normalize':normalize, 
     } 

     return type('submethods', (object,), callables_dict) 
    #... 

を次のようにしたい(私は推測)として次にあなたが

>>> TestClass(data).preprocessing.gradient 
<unbound method submethods.gradient> 

または

>>> TestClass(data).preprocessing.normalize 
<unbound method submethods.normalize> 
をやって、あなたのサブメソッドを呼び出すことができます type Dの辞書を返すことについてどのような、そうでない場合

あなたがやりたいことに応じて、キャッシュするのは良い考えです。preprocessingは、呼び出されるたびに内部関数を再定義しないようにします。


しかし既に述べたように、これはおそらく最善の方法ではありません。

+0

代わりに 'class'文を代わりに使うことができたときに、プロパティメソッド内で型を構築するのはどうしてですか? '@property def preprocessing'をclass preprocessing'に置き換え、' callables_dict'と 'return'文を取り除いて、あなたは何か同等のものを持っていますが、あなたが示したものよりも優れています。それは本当に質問者が望んでいるかどうかわからない... – Blckknght

+1

@Blckknght。同等かより良い?実際に私はそうしています。なぜなら[ほとんどのPython開発者はクラスをネストしないので、そうすると規約を破ってメンテナンスコストを増やします。](https://stackoverflow.com/a/30376236/4194079)。それは私がOPが何を望んでいるかを理解するのは100%ではないと言われています:) – Kanak

+0

私は 'class'文を使ってクラスを構築することは、辞書にメソッドを投げたり、実行時にクラスをビルドするために手動で' type'を呼び出すことよりも常に良いと思います。その理由は、あなたのバージョンが束を別々に作成するということです。彼らは同じ内容を持っていますが、同じクラスではありません。isinstance(x.preprocessing()、x.preprocessing)のようなものを試してみるととても混乱するかもしれません。しかし、私はおそらく、質問者のデザインはあまり良くないと思うし、内部クラスを完全に避けることがさらに良いと思うと思う。 – Blckknght

関連する問題