3

Python を使用して 3 日目なので、初心者の間違いをお許しください。だからここに私の作業コードがあります。person.test()が上司にコールバックを登録し、上司がコールバックを呼び出し、すべて正常に動作します。

class Boss:
  def registerCallback(self,cb):
    self.cb = cb
  def doCallback(self):
    self.cb()

class Person:
  def woot(self,data):
    print("Woot! ",data)

  def test(self,boss,data):
    def callback ():
      self.woot(data)
    boss.registerCallback(callback)    

boss = Boss()
person = Person()
person.test(boss,1)
boss.doCallback()

ただし、コールバックを exec() に変更すると、クロージャが失われます。コールバックは実行されますが、selfdataが不明であるため、self.woot(data)の呼び出しは失敗します。

class Boss:
  def registerCallback(self,cb):
    self.cb = cb
  def doCallback(self):
    self.cb()

class Person:
  def woot(self,data):
    print("Woot! ",data)

  def test(self,boss,data):
    x = "def callback():\n  self.woot(data)\nboss.registerCallback(callback)"
    exec(x,globals(),locals())

boss = Boss()
person = Person()
person.test(boss,1)
boss.doCallback()

私も compile() を試みましたが、うまくいきませんでした。何かご意見は?私の実際のコードははるかに複雑であるため、上司との間で自己/データのコピーを手動で持ち歩きたくありません。閉鎖を維持する方法が本当に必要です。

4

2 に答える 2

3

(関数のグローバルデータとして)渡すだけの場合locals、多かれ少なかれ機能します:

class Person:
  def woot(self,data):
    print("Woot! ",data)

  def test(self,boss,data):
    x = "def callback():\n  self.woot(data)\nboss.registerCallback(callback)"
    exec(x, locals())

もちろん、グローバルも必要な場合は、それらを一緒にパックできます。

def test(self, boss, data):
  namespace = globals().copy()
  local_copy = locals().copy()
  namespace.update(local_copy)
  x = 'def foo(): pass'
  exec(x, namespace)
于 2015-03-09T20:26:21.577 に答える