私は自分の髪の毛を裂いています:この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()
注:
ありがとう、私はあなたがそれを持っていると思う、あなたは正しい私のコードはもっと最小だった可能性があります...マルチプロセッシングの面が問題の一部であるかどうかはわかりませんでした。 私はself.my_dictionaryを設定することを意味しました["new_string"] = '私が変なことを起こすのを見てください! ... 元のデモコードでこの修正を行うと、期待した結果が得られます。 残念ながら、元のプログラムで同じ修正を行うことはありません!私はまだ、プログラムが終了するときにデータの実行()が辞書に追加されているところで、「schitzophrenic変数」の効果を得ています。 – right2clicky
@ right2clickyあなたは他の場所で同様のことをしているにちがいありません。単純に言えば、あなたが描いている効果はそれだけで起こるわけではありません。あなたのデモがどこで違うのか探してみてください。 – Carcigenicate
さて、私はself.my_dictionaryに相当する変数のコードを検索しました。ここに私がすることがあります: __init__:{}に初期化されます... 体の機能:len()... 体の機能:。追加する(somedata)... 体機能:.pop(index)... 体機能:。拡張(somedata)... ...と同様に変数からデータを取得する。それでおしまい! そして、それらのどれがそれをどのようにclobberまたは上書きするかわかりません... – right2clicky