2016-02-09 4 views
8

愚かな質問ですが、これは私の偽りのためのdownvotesに関係なく私を悩ましています:メソッドが使用するメソッドの外でデータを生成するという無意味な恐怖を拾いました(変更なし)、これが当てはまるかどうかわかりません。メソッドの外でデータを生成するPythonicの方法

私はメソッドmyfxを持っているとしましょう。それには長時間の操作が必要な辞書datadexが必要ですが、そのセッション中のすべての呼び出しに共通するものがあります。最も簡単な方法は実行可能ではありません。

しかし、それはあまりにも多くの時間を無駄にします。だから、最高のものは、1つのクラス変数と同じように、一度メインスコープでそれを作るために次のようになります。

datadex={f:42 for f in foo} #initialise 
def myfx(x): 
    mungeddata=datadex[x]+1 #munge 
    return mungeddata 

しかし、私はなぜ知らないが、私はこれを回避するために偉大な長さに行きます。それは控えめですが、私はそうではないと思います。私は通常閉鎖に頼っています:

def initialise(foo): 
    datadex={f:42 for f in foo} #initialise 
    def myfx(x): 
     mungeddata=datadex[x]+1 #munge 
     return mungeddata 
    return myfx 

悪いことにクラスを作る。 PythonとJSでほぼ独占的にコード化しています。私の最高の推測は、私のPerlのコード化日からの後退である - 無意識のうちに私は自分自身が変数を書くことを最初にすべてパスカルなので、いくつかの習慣が影として残っていると思うが、クラスやクロージャの方法についてはOO-全然違う。

+0

「理由はわかりませんが、私はこれを避けるためにすばらしい長さに行きます。あなたは本質的に関数型プログラミングを考えているようですが、定義された変数は変更できません。 – Izkata

+0

(a)あなたの質問は何ですか? (b)単純にdatadexを引数に渡して使用するとは考えていませんか? – jwodder

+3

ええ、 'initialise'メソッドは基本的に部分関数アプリケーションを実行しています。 [functools](https://docs.python.org/3/library/functools.html)には、[partial](https://docs.python.org/3/library/functools)というヘルパーがあります。 html#functools.partial) – dtanders

答えて

6

クラスは、この動作をカプセル化する正しい方法です。複数の関数呼び出しで共有されるデータがあります。

class MungedData(object): 

    def __init__(self, foo): 
     self.datadex = {f:42 for f in foo} 

    def myfx(self, x): 
     return self.datadex[x] + 1 

md = MungedData(somefoo) 
print(md.myfx(arg1)) 
print(md.myfx(arg2)) 

確かに他の選択肢がありますが、これはPythonで最も一般的で簡単な方法です。あなたはこのような何かを行うことができ、クラス内のあなたの機能を持たせたくない場合は

2

Python関数は、オブジェクトであり、属性を持つことができます。

def myfx(x): 
    mungeddata=myfx.datadex[x]+1 #munge 
    return mungeddata 
myfx.datadex={f:42 for f in foo} #initialise 

私はあなたが避けるようにしようとしているものであることを推測しますグローバル変数を持つ。

+2

これは、@Brendan Abelが上記のコメントでそれを呼んだように、 "OOのハックな形"を使って問題を解決しようとしているようです。これは、JSなどの適切なOOが利用できない場合には理にかなっていますが、なぜPythonでそれを制限するのでしょうか? – Nico

+0

関数が属性を取ることができるという事実は、Pythonがどのように設計されているのかという事故であり、利用する機能ではありません。私はそれが使用されていることを今まで見たことがないか分かりません。 – chepner

+0

@Nico JSには「適切なOO」がありませんか?私は知らなかった、私がそれについて読んだことはすべて間違っていなければならない。 Pythonはマルチパラダイムであり、開発者にスタイルを強いることはなく、フリー関数には何も問題はありません。 – imreal

0

実際にオブジェクト指向プログラミングを避けたい場合は、get_dict()がディクティックを格納するためにジェネレータを使用するマップを作成するために以下を実行できます。

def get_dict(): 
    d = {f:42 for f in foo} 
    while True: 
    yield d 

def myfx(x): 
    datadex = get_dict() 
    return datadex[x]+1 #munge 

return myfx 
関連する問題