が記載されていないのはなぜ輸入防止の定義がどこにも、pythonスクリプト実行とexecfile()?

StackOverflow https://stackoverflow.com/questions/2348630

質問

また、既存の多くの質問の定義がどこにも例外がスクリプトを実行しexec諸表またはexecfile()Pythonでは、がんと説明し、次の行為です。

したいのですが、簡単なゲームを生成するスクリプトオブジェクトの整列を実行とexecfile().以下の4つのモジュールこの問題(ご負担いただくことしてたくさんです!)本プログラムを読み込むスクリプトを使用execfile()で呼び出スクリプトマネージャーのスクリプトオブジェクト

# game.py

import script_mgr
import gamelib  # must be imported here to prevent NameError, any place else has no effect

def main():
  execfile("script.py")
  script_mgr.run()

main()

スクリプトファイルであって、オブジェクトを生成し秘密の質問:あなたの音を追加しますオブジェクト一覧のスクリプトマネージャー:

 script.py

import script_mgr
#import gamelib # (has no effect here)

class ScriptObject:
  def action(self):
    print("ScriptObject.action(): calling gamelib.play_sound()")
    gamelib.play_sound()

obj = ScriptObject()
script_mgr.add_script_object(obj)

スクリプトに長けのアクション()関数の各スクリプト:

# script_mgr.py

#import gamelib # (has no effect here)

script_objects = []

def add_script_object(obj):
  script_objects.append(obj)

def run():
  for obj in script_objects:
    obj.action()

のgamelib機能が定義された第四のモジュールの面倒なれまでのアクセス

# gamelib.py

def play_sound():
  print("boom!")

上記のコードは以下の出力:

mhack:exec $ python game.py
ScriptObject.action(): calling gamelib.play_sound()
boom!
mhack:exec $ 

しかし、だいてわかりやすく解説してい厳しい環境下において"インポートすgamelib声明にgame.py とstrncasecmpの"インポートすgamelib"のscript.pyを取得し、以下のエラー:

mhack:exec $ python game.py
ScriptObject.action(): calling gamelib.play_sound()
Traceback (most recent call last):
  File "game.py", line 10, in 
    main()
  File "game.py", line 8, in main
    script_mgr.run()
  File "/Users/williamknight/proj/test/python/exec/script_mgr.py", line 12, in run
    obj.action()
  File "script.py", line 9, in action
    gamelib.play_sound()
NameError: global name 'gamelib' is not defined

私の質問は1)なぜそのような輸入に必要なのgame.py'モジュールのexecsのスクリプト?2)が記載されていないのはなぜで輸入'gamelibからモジュールで参照される(script.py又はモジュールと呼ばれる(script_mgr.py)?

このPython2.5.1

役に立ちましたか?

解決

から Pythonドキュメント のためのexecfile:

execfile(ファイル名[,globals[,地]])

場合には地元の辞書を省略してデフォルトでは、グローバル変数辞書で調べました。辞書が両方とも省略された場合、その表現は環境の下で実行されるexecfile()が呼び出されます。

あるオプション引数execfile.以降を省略する多岐にわたって、スクリプトが実行されている環境がexecfileが呼び出されます。その理由の輸入game.py 変更の内容を構築します。

また、結論は以下の行動の輸入game.py やscript.py:

  • にgame.py import gamelib 輸入のgamelibモジュール 両globalsおよびlocals.これは、環境に渡されるscript.py そのgamelibによりアクセス可能なScriptObject行動の方法からアクセスがグローバル変数).

  • にscript.py import gamelib 輸入のgamelibモジュール 地元の人々のみ (トの特定ができない理由).だからアクセスしようとしているgamelibからScriptObjectアクションメソッドからグローバル変数の定義がどこにも.で移動した場合は、輸入の範囲の行動方法を次のようにgamelibまからアクセスできる地):

    class ScriptObject:
        def action(self):
            import gamelib
            print("ScriptObject.action(): calling gamelib.play_sound()")
            gamelib.play_sound()
    

他のヒント

それは(game.pyメインのローカルスコープにインポートするため、このインポートが実行される範囲であるため、

script.pyの「インポートgamelib」は影響を及ぼさない理由は、)です。このスコープは、それが実行ScriptObject.action()のための可視範囲ではありません。

グローバルの変化()や地元の人々をプリントアウトするためにデバッグコードを追加するには、()プログラムの以下の修正版で何が起こっているのかを明らかに

# game.py

import script_mgr
import gamelib  # puts gamelib into globals() of game.py

# a debug global variable 
_game_global = "BEF main()" 

def report_dict(d):
  s = ""
  keys = d.keys()
  keys.sort() 
  for i, k in enumerate(keys):
    ln = "%04d %s: %s\n" % (i, k, d[k])
    s += ln
  return s

def main():
  print("--- game(): BEF exec: globals:\n%s" % (report_dict(globals())))
  print("--- game(): BEF exec: locals:\n%s" % (report_dict(locals())))
  global _game_global 
  _game_global = "in main(), BEF execfile()"
  execfile("script.py")
  _game_global = "in main(), AFT execfile()"
  print("--- game(): AFT exec: globals:\n%s" % (report_dict(globals())))
  print("--- game(): AFT exec: locals:\n%s" % (report_dict(locals())))
  script_mgr.run()

main()
# script.py 

import script_mgr
import gamelib  # puts gamelib into the local scope of game.py main()
import pdb # a test import that only shows up in the local scope of game.py main(). It will _not_ show up in any visible scope of ScriptObject.action()!

class ScriptObject:
  def action(self):
    def report_dict(d):
      s = ""
      keys = d.keys()
      keys.sort()
      for i, k in enumerate(keys):
        ln = "%04d %s: %s\n" % (i, k, d[k])
        s += ln
      return s
    print("--- ScriptObject.action(): globals:\n%s" % (report_dict(globals())))
    print("--- ScriptObject.action(): locals:\n%s" % (report_dict(locals())))
    gamelib.play_sound()

obj = ScriptObject()
script_mgr.add_script_object(obj)

ここでは、プログラムのデバッグ出力があります:

--- game(): BEF exec: globals:
0000 __builtins__: 
0001 __doc__: None
0002 __file__: game.py
0003 __name__: __main__
0004 _game_global: BEF main()
0005 gamelib: 
0006 main: 
0007 report_dict: 
0008 script_mgr: 

--- game(): BEF exec: locals:

--- game(): AFT exec: globals:
0000 __builtins__: 
0001 __doc__: None
0002 __file__: game.py
0003 __name__: __main__
0004 _game_global: in main(), AFT execfile()
0005 gamelib: 
0006 main: 
0007 report_dict: 
0008 script_mgr: 

--- game(): AFT exec: locals:
0000 ScriptObject: __main__.ScriptObject
0001 gamelib: 
0002 obj: 
0003 pdb: 
0004 script_mgr: 

--- ScriptObject.action(): globals:
0000 __builtins__: 
0001 __doc__: None
0002 __file__: game.py
0003 __name__: __main__
0004 _game_global: in main(), AFT execfile()
0005 gamelib: 
0006 main: 
0007 report_dict: 
0008 script_mgr: 

--- ScriptObject.action(): locals:
0000 report_dict: 
0001 self: 


boom!

の代わりgame.pyまたはscript.pyのモジュールレベルでの輸入を入れしようとしているのは、私は、スクリプトオブジェクトのメンバ関数のローカルスコープにimport文を入れて由紀子の提案に従います。これは私には少しぎこちないと思われる、とexec'dスクリプトのように輸入を指定するためにいくつかのより良い方法があるかもしれませんが、少なくとも私は今何が起こっているかを理解します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top