compile()
、マーシャルモジュール、およびで遊んでいる間exec
。私はいくつかの紛らわしい行動に遭遇しました。検討 simple.py
def foo():
print "Inside foo()..."
def main():
print "This is a simple script that should count to 3."
for i in range(1, 4):
print "This is iteration number", i
foo()
if __name__ == "__main__":
main()
exec
このようにこのスクリプトを実行すると
with open('simple.py', 'r') as f:
code = f.read()
exec code
期待される出力が得られます。
This is a simple script that should count to 3.
This is iteration number 1
This is iteration number 2
This is iteration number 3
Inside foo()...
しかし、私が紹介するcompile()
と、、、marshal.dump()
そしてmarshal.load()
このように
import marshal
def runme(file):
with open(file, "r") as f:
code = marshal.load(f)
exec code
with open("simple.py", "r") as f:
contents = f.read()
code = compile(contents, "simple.py", "exec")
with open("marshalled", "w") as f:
marshal.dump(code, f)
runme("marshalled")
期待される出力の先頭を出力してからエラーを出力します
This is a simple script that should count to 3.
This is iteration number 1
This is iteration number 2
This is iteration number 3
Traceback (most recent call last):
File "./exec_within_function.py", line 17, in <module>
runme("marshalled")
File "./exec_within_function.py", line 8, in runme
exec code
File "simple.py", line 15, in <module>
main()
File "simple.py", line 12, in main
foo()
NameError: global name 'foo' is not defined
なぜそれfoo
が定義されていないと言うのですか?
理解するために、このように使ってdir()
みました
import simple # imports simple.py
dir(simple)
そして予想通り、それfoo
は定義されていることを示しています。
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'foo', 'main']
dis.dis()
また、逆シリアル化されたコードオブジェクト(を介して読み取る)で使用する場合、表示されるのはand formarshal.load()
だけであることに気付きましたが、このように使用するとLOAD_NAME
CALL_FUNCTION
main()
import
import dis, sys
import simple
dis.dis(sys.modules["simple"])
それは私に期待通りに全体の分解を与えます。
Pythonがコンパイルに使用するコードのいくつかを見たことがありimport
ます。定義に何らかのルックアップテーブルを使用していると思いますがcompile()
、この動作の原因となる違いが何であるかはわかりません。