2011-09-13 9 views
3

1つのメソッドから、類似しているが排他的に呼ばれる関数を扱う必要があります。例えば(そうでないかもしれない素晴らしい例)Python、メソッドから複雑なデータを返す/処理する最良の方法

class Util(object): 
    def method1(self): 
     return "method1", [1,2,3] 

    def method2(self): 
     return "method2", {"1":4, "2":5, "3":6} 

    def method3(self): 
     return [1,2,3], "method3", {"1":4, "2":5, "3":6} 

    def call_method(self, method_func): 
     if method_func.__name__ == "method1": 
      (name, dict_values) = self.method_func() 
     if method_func.__name__ == "method2": 
      (name, list_values) = self.method_func() 
     if method_func.__name__ == "method3": 
      (list_values, name, dict_values) = self.method_func() 
     # How best to manage a return for 3 optional, but not inter-dependent values? 
     return name, dict_values, list_values 

if __name__ = "__main__": 
    u = Util() 
    (name, dict_values, list_values) = u.call_method(Util.method1) 

call_method()の戻り私はここに視覚化しようとしているものです。私は、私が作る必要がある排他的なサブコールの束を持っている、私はそれらを返すことができるものにそれらをマッサージする必要があります。

Utilクラスのメンバ変数に追加するのは簡単でしょうか? u.call_method()を実装する人は、単に何を探すべきかを知る必要があります。

誰もが最初にデザインについて不平を言う前に、それは私のものではありません。私は一貫したAPIを公開し、このようなリターンをどのように処理するかについての意見を聞くだけでよい。これは簡単に正規化されていませんし、行方不明の戻り値がランタイムに合格しますが、先行する戻り値は渡されません。

ヒントがあれば大丈夫です!ありがとうございました。

+2

'return name、dict_values、list_values'の何が問題になっていますか?あなたは何の問題があるのか​​分かりません。 –

答えて

1

をあなたは、多くの場合、アプローチは、辞書を使用しているグループのいくつかの値に必要がある場合が...つまり、あなたのコードを変更:

... 
def method1(self): 
    return {"name": "method 1", 
      "list": [1, 2, 3]} 

Pythonで可能である何かがオブジェクトの代わりに辞書を使用することです

class Bunch: 
    def __init__(self, **kwargs): 
     self.__dict__.update(kwargs) 

... 
def method1(self): 
    return Bunch(name="method1", 
       list=[1, 2, 3]) 

を呼び出し側がresult.name代わりのresult["name"]を使用できるように:読むためのコードはよりよい作るためにionary。

最近Pythonで標準化された別のオプションはNamedTupleです。

+0

私はそれが好きです。フィードバックいただきありがとうございます。 – garlicman

+0

namedtuple(below)は少し洗練された方法でこれを行いますが、まだタプルのような開梱値を使用することができます –

+0

Dunch(name = "method"、list = [1,2,3] ) – rocksportrocker

1

あなたがメソッド変更することができた場合:

class Util(object): 
    def method1(self): 
     return "method1", [1,2,3], None 

    def method2(self): 
     return "method2", None, {"1":4, "2":5, "3":6} 

    def method3(self): 
     return "method3", [1,2,3], {"1":4, "2":5, "3":6} 

    def call_method(self, method_func): 
     return method_func(self)  

if __name__ == "__main__": 
    u = Util() 
    (name, dict_values, list_values) = u.call_method(Util.method1) 
    # better: 
    print u.method1() 

そして、あなたが変更できない場合:

class Util(object): 
    def method1(self): 
     return "method1", [1,2,3] 

    def method2(self): 
     return "method2", {"1":4, "2":5, "3":6} 

    def method3(self): 
     return "method3", [1,2,3], {"1":4, "2":5, "3":6} 

    def call_method(self, method_func): 
     results = method_func(self) 
     name = list_ = dict_ = None 
     for obj in results: 
      if isinstance(obj, string): 
       name = obj 
      elif isinstance(obj, list): 
       list_ = obj 
      elif isinstacne(obj, dict): 
       dict_ = obj 
     return name, dict_, list_ 

if __name__ == "__main__": 
    u = Util() 
    (name, dict_values, list_values) = u.call_method(Util.method1) 
3

namedtupleは、呼び出し側はそれが彼らの唯一のいくつかを読んで必要な場合は、すべてのタプルメンバーを抽出する必要はありません。この方法で「無名」のタプル

http://docs.python.org/library/collections.html#collections.namedtuple

を返すために非常にPython的な選択肢です。

+0

+1名前付きタップ!タプルを返す場所であれば、代わりにnamedtupleを返すようにコードを変更してください。それをやりなさい。 – jathanism

+0

namedtuplesを持つ唯一のniggleは固定フィールドセットです。設定されていないフィールドをNoneやその他のものにデフォルト設定する明白な方法はありません。例えば1つのケースでは、3つのフィールドのうち2つのフィールドのみが人口に利用可能であり、別のケースでは3つのフィールドのうちの3つが利用可能である。名前付きタプルで定義されたすべてのフィールドには常に値を設定する必要があります。名前付きタプルを構築するときに欠落しているフィールドのデフォルト値を設定できるとすばらしいでしょう。 – garlicman

+0

Pythonはその目的のためにNoneを持っています:)しかし、docsはおそらく、すべての値をNoneに初期化する独自のnamedtuple実装(サブクラス)を作成できると主張しています。 –