2017-09-20 5 views
0

私は自分の髪の毛を裂いています:このPythonクラスの可変スコープの動作は、まったく予想外のことであり、率直に変わっています。どうしたの?

私は、複数のプロセスプログラムを持っており、それぞれが与えられたタスクを担当しています。

KeyboardInterruptが来ると、各作業者は内部状態をファイルに保存して、次回中断した場所で作業を続けることができます。これが起こることができる前の状態に関する情報が含まれていた辞書が消えているよう

しかし...

に見えます!

どのようにですか? exit()関数は、よりグローバルにスコープされたバージョンの辞書にアクセスしています。さまざまなrun()(およびsubordinate to run())関数が独自のバージョンの変数を作成しています。

そのことについて奇妙な何も...

...除き、それらのすべては、自己を使用しています。キーワード。

私の理解が正しいとすれば、それらが常に変数のインスタンス全体のバージョンにアクセスしていることを意味するはずです。

import multiprocessing 
import atexit 
import signal 
import sys 
import json 

class Worker(multiprocessing.Process): 
    def __init__(self, my_string_1, my_string_2): 
     # Inherit the __init_ from Process, very important or we will get errors 
     super(Worker, self).__init__() 
     # Make sure we know what to do when called to exit 
     atexit.register(self.exit) 
     signal.signal(signal.SIGTERM, self.exit) 
     self.my_dictionary = { 
      'my_string_1' : my_string_1, 
      'my_string_2' : my_string_2 
      } 
    def run(self): 
     self.my_dictionary = { 
      'new_string' : 'Watch me make weird stuff happen!' 
      } 
     try: 
      while True: 
       print(self.my_dictionary['my_string_1'] + " " + self.my_dictionary['my_string_2']) 
     except (KeyboardInterrupt, SystemExit): 
      self.exit() 
    def exit(self): 
     # Write the relevant data to file 
     info_for_file = { 
      'my_dictionary': self.my_dictionary 
      } 
     print(info_for_file) # For easier debugging 
     save_file = open('save.log', 'w') 
     json.dump(info_for_file, save_file) 
     save_file.close() 
     # Exit 
     sys.exit() 

if __name__ == '__main__': 
    strings_list = ["Hello", "World", "Ehlo", "Wrld"] 
    instances = [] 
    try: 
     for i in range(len(strings_list) - 2): 
      my_string_1 = strings_list[i] 
      my_string_2 = strings_list[i + 1] 
      instance = Worker(my_string_1, my_string_2) 
      instances.append(instance) 
      instance.start() 
     for instance in instances: 
      instance.join() 
    except (KeyboardInterrupt, SystemExit): 
     for instance in instances: 
      instance.exit() 
      instance.close() 

キーmy_string_1が明示的に時に追加されたにも関わらず、言い換えれば

Process Worker-2: 
Process Worker-1: 
Traceback (most recent call last): 
    File "/usr/lib/python3.5/multiprocessing/process.py", line 249, in _bootstrap 
    self.run() 
Traceback (most recent call last): 
    File "/usr/lib/python3.5/multiprocessing/process.py", line 249, in _bootstrap 
    self.run() 
    File "<stdin>", line 18, in run 
    File "<stdin>", line 18, in run 
KeyError: 'my_string_1' 
KeyError: 'my_string_1' 

...私たちは、次のトレースバックを取得し、実行の場合:ここで

は、コードの簡易版ですinit、run()関数は、そのキーを含まない新しいバージョンのself.my_dictionaryにアクセスしています!

ここでも、我々は通常の変数(代わりにself.my_dictionaryのmy_dictionary)を扱った場合、これが予想されるが、私はself.variablesは常にインスタンス全体と思っていた...

ここで何が起こっていますか? runが何をしているか

class Test: 
    def __init__(self): 
     self.x = 1 

    def run(self): 
     self.x = 2 

     if self.x != 1: 
      print("self.x isn't 1!") 

t = Test() 
t.run() 

注:

答えて

0

あなたの問題は、基本的には次で表すことができます。

あなたが次に

self.my_dictionary = { 
      'new_string' : 'Watch me make weird stuff happen!' 
} 

を書くときあなたのインスタンスメンバself.my_dictionaryは、あなたが

print(self.my_dictionary['my_string_1']... 

を言うとき、それはときに、あなたの意図がある正確にどのようなはっきりしていないこと、互換性のないデータを使用しようと互換性のないデータで上書きmy_dictionaryを上書きしますが、そのためエラーが発生しています。論理を再考する必要があります。

+0

ありがとう、私はあなたがそれを持っていると思う、あなたは正しい私のコードはもっと最小だった可能性があります...マルチプロセッシングの面が問題の一部であるかどうかはわかりませんでした。 私はself.my_dictionaryを設定することを意味しました["new_string"] = '私が変なことを起こすのを見てください! ... 元のデモコードでこの修正を行うと、期待した結果が得られます。 残念ながら、元のプログラムで同じ修正を行うことはありません!私はまだ、プログラムが終了するときにデータの実行()が辞書に追加されているところで、「schitzophrenic変数」の効果を得ています。 – right2clicky

+0

@ right2clickyあなたは他の場所で同様のことをしているにちがいありません。単純に言えば、あなたが描いている効果はそれだけで起こるわけではありません。あなたのデモがどこで違うのか探してみてください。 – Carcigenicate

+0

さて、私はself.my_dictionaryに相当する変数のコードを検索しました。ここに私がすることがあります: __init__:{}に初期化されます... 体の機能:len()... 体の機能:。追加する(somedata)... 体機能:.pop(index)... 体機能:。拡張(somedata)... ...と同様に変数からデータを取得する。それでおしまい! そして、それらのどれがそれをどのようにclobberまたは上書きするかわかりません... – right2clicky

関連する問題