2017-03-21 9 views
0

TL; DR関数から辞書への2種類のデータ(辞書やリストなど)をグローバルな名前空間の辞書とリストに渡すにはどうすればいいですか? ?Python2.7 - グローバル名前空間への関数リストと辞書の受け渡し

私は自分の機器と対話するスクリプトを書いています。このスクリプトでは、CSVを含む複数のテキストファイルを提供する必要があります。これらの値は、必要に応じてリストと辞書に入れられます。

ファイルは同じように処理されるため、処理コードを関数に入れました(DRYの精神の中で)。問題は、関数の実行回数に関係なく、すべてのリストエントリを単一のリストに追加し、すべての辞書エントリを1つの辞書に追加したいということです。しかし、私はこれのスコープ側で問題を抱えています。

私の理解では、関数はローカル名前空間にあります。このため、グローバルな名前空間の 'マスター'リストと辞書に関数を追加することはできません(グローバル変数を使用せず、もちろんnoです)。

グローバルな名前空間でデータを利用できるように関数から値を返すことができますが、私が理解しているところでは、タプル、辞書などのような1つの形式でしか返すことができません。私のニーズにも合わないでしょう。

私の質問は、関数から辞書とグローバル名前空間のリストに2種類のデータ(辞書やリストなど)を渡すにはどうすればよいですか?

+1

なぜタプルを返すのがあなたに合わないのですか? [最小、完全で、検証可能な例](https://stackoverflow.com/help/mcve) –

+0

なしで本当にあなたを助けることは難しいです。それは良い点です。私はすべての将来の質問のためにそれをしなければなりません。 tdelaneyの答えは、私が探していたもので、実際に私がしようとしているものの素晴らしい例が含まれています。 – Vopier

答えて

0

そのないグローバル名前空間自体には、いや、その「マスター」リストと辞書ませんglobalキーワード。問題は全体的な柔軟性を低下させたことです(他のコードがモジュールをインポートして独自のコンテナを管理したい場合)、管理しにくいコードを作成しました(これらのコンテナに触れる場所をすべて追跡する必要があります) 。これらは設計のトレードオフであり、お客様の環境で受け入れることが合理的かもしれません。

これらはコンテナであり、関数内のモジュールグローバル名前空間から変数を読み込むことはできます(再割り当てすることはできません)。globalキーワードなしで変数を使用できます。グローバル変数を使用していることに注目してください。

my_list = [] 
my_dict = {} 

def func(): 
    while True: 
     filename = input("Enter csv file, or 'done'") 
     if filename == 'done': 
      break 
     my_list.append(filename) 
     # not sure what to add to dict, but you get the point 

def main(): 
    # this adds to the global containers 
    func() 
    # but be careful, this adds to the global containers and skips these 
    # local versions 
    my_list = ['foo'] 
    my_dict = {'bar':'baz'} 
    func() # doesn't change the local objects 

必要に応じて関数に渡すことによって、グローバル名前空間からコンテナを切り離すことができます。

def func(my_list, my_dict): 
    while True: 
     filename = input("Enter csv file, or 'done'") 
     if filename == 'done': 
      break 
     my_list.append(filename) 
     # not sure what to add to dict, but you get the point 

def main(): 
    # this adds to the local containers 
    my_list = ['foo'] 
    my_dict = {'bar':'baz'} 
    func(my_list, my_dict) 

また、これらのコンテナを独自のクラスにバンドルすることもできます。これは、これらのコンテナを使用する関数の多くをクラスに追加したい場合があるため、より多くのリフトです。

class MyContainers: 

    def __init__(self): 
     self.my_list = [] 
     self.my_dict = {} 

    def func(self): 
     while True: 
      filename = input("Enter csv file, or 'done'") 
      if filename == 'done': 
       break 
      self.my_list.append(filename) 
      # not sure what to add to dict, but you get the point 

def main(): 
    foo = MyContainers() 
    foo.func() 
    print(foo.my_list) 
    print(foo.my_dict) 
+0

素晴らしい応答と私が探しているものです。関数がグローバル名前空間の変数に追加することが可能であることを完全に忘れてしまった。あなたの答えにあなたの時間を感謝します。 – Vopier

1
def func(): 
    return [1,2], {'abc':5} 

alist, dictionary = func() 

print alist, dictionary 
Output: [1,2] {'abc': 5} 

print type(alist), type(dictionary) 
Output: (type 'list') (type 'dict') 
+0

'list'を変数名として使用しないでください。組み込みの' list'関数を隠してしまい、微妙で検出しにくいバグにつながる可能性があります。 –

+0

良い点、ありがとう。私はちょうど説明のためにそれを使用しようとしていました。それを編集しました。 –

+0

これは問題を解決しません。 OPは既存のコンテナを更新するために 'func'への複数の呼び出しを望みます。 – tdelaney

関連する問題