When it’s ready.

出来るまで出来ない

Pythonのスコープで再び迷子 

id:mopemope氏と、id:jbking氏に優しく突っ込まれ、グローバル変数なんて使うのやめたと思い。クラスを作ってメンバ変数で値持たせてみました。使うときは、ゲッタとセッタでしこしこ出し入れすることにしました。

そんで再び迷子、やったことは。
変数は、GDataクラスのインスタンスgDataに持たせる。
それを、ModMainクラスのインスタンスmodMainから利用する。
ただし、modMainは、子プロセスで動かす。

modMainをstart()させて、しばらくたってから、modMainの外からgDataのセッターで中身を書き換えてみると・・・
modMainのgDataには何の影響も及ぼさないよ!

modMain起動するときにgDataを渡してないから、modMainは空気を読んでgDataから値を取ってきてると思ったけど、そういう挙動になってないと言うことは、.start()するときの、自分とそのときに存在するインスタンスの情報もすべてまるっと、自分の空間にコピーしてしまうのかな?もしそうだったら、だれかを.start()するときに、全く関係ない超巨大なインスタンスが存在したら、その分ドカドカとメモリが倍々になっていくということか!?

いまいち挙動が読めない・・

以下、テストに使ったコード

#!/usr/bin/env python
# coding:utf-8

from multiprocessing import Process
from time import sleep

class GData():
  # このプログラムで使う変数を受け持つクラス
  def __init__(self):
    self.a = 100
    self.b = 'hoge'

  def getData(self):
    return (self.a, self.b)

  def setData(self, a=None, b=None):
    self.a = a
    self.b = b


class ModMain():
  # mainでグルグル回り処理する子
  def __init__(self):
    self.cnt = 20

  def run(self):
    while self.cnt:
      print gData.getData()
      self.cnt += -1
      sleep(0.2)

gData = GData()
modMain = ModMain()

Process(target = modMain.run).start()

sleep(1)
gData.setData(a=1, b='foo')

print '-' * 80
print gData.getData()
print '-' * 80

結果

(100, 'hoge')
(100, 'hoge')
(100, 'hoge')
(100, 'hoge')
(100, 'hoge')
--------------------------------------------------------------------------------
(1, 'foo')
--------------------------------------------------------------------------------
(100, 'hoge')
(100, 'hoge')
(100, 'hoge')
(100, 'hoge')
(100, 'hoge')
(100, 'hoge')
(100, 'hoge')
(100, 'hoge')
(100, 'hoge')
(100, 'hoge')
(100, 'hoge')
(100, 'hoge')
(100, 'hoge')
(100, 'hoge')
(100, 'hoge')

ハァ
悩みは尽きず・・・