2

文字列から大量の Python コードを実行できるようにする必要があります。コードexecは通常の設定で完全に実行されますが、この方法で実行するとエラーが発生するようです。また、インターネット上でホストされているため、インポートすることはできないと思います。コードは次のとおりです。

import urllib.request

URL = "https://dl.dropboxusercontent.com/u/127476718/instructions.txt"  

def main():
    instructions = urllib.request.urlopen(URL)

    exec(instructions.read().decode())

if __name__ == "__main__":
    main()

これは私が得ているエラーです:

Traceback (most recent call last):
  File "C:\Python33\rc.py", line 12, in <module>
    main()
  File "C:\Python33\rc.py", line 9, in main
    exec(instructions.read().decode())
  File "<string>", line 144, in <module>
  File "<string>", line 120, in main
NameError: global name 'Player' is not defined

実行しようとしているコードは、最初のコード スニペットのリンクにあります。

ご不明な点がございましたら、お答えいたします。ありがとうございました。

4

3 に答える 3

3

グローバルを指定しないと、exec関数(Python/bltinmodule.c) はPyEval_GetGlobals()andを使用しPyEval_GetLocals()ます。関数の実行フレームの場合、後者は新しいf_localsdict を作成します。これは、コンパイルされたコードのIMPORT_NAMESTORE_NAME、 ops のターゲットになります。LOAD_NAME

Python のモジュール レベルでは、通常の状態はglobals() == locals(). その場合STORE_NAME、モジュールのグローバルを使用します。これは、モジュール内で定義された関数がそのグローバル名前空間として使用するものです。ただし、グローバルとローカルに別々の辞書を使用すると、明らかにその前提が崩れます。

globals解決策は、次のexecようにも使用されるを手動で供給することlocalsです。

def main():
    instructions = urllib.request.urlopen(URL)
    exec(instructions.read().decode(), globals())

__name__次のように定義された新しい dict を使用することもできます。

def main():
    instructions = urllib.request.urlopen(URL)
    g = {'__name__': '__main__'}
    exec(instructions.read().decode(), g)

ソースを見ると、現在のディレクトリには「pickup.wav」という名前のサウンド ファイルが必要であることがわかります。そうしないと、別のエラーが発生します。

もちろん、execこのような使用に関するセキュリティ上の問題についてのコメントは引き続き適用されます。私は名前空間の専門性についてのみ言及しています。

于 2013-04-14T13:53:01.693 に答える
1

__import__まず、StringIO オブジェクトを試してみるかもしれないと思いました。StackOverflow: Local Import Statements in Pythonのように見えるかもしれません。

...しかし、それは正しくありません。

次に、impモジュールを使用することを考えましたが、それも機能していません。

それから私は見ました: Python での Eval の使用に対する Alex Martelli の回答--- そして、自分でばかげたコードでそれを使用しようとしました。

astオブジェクトとその結果を取得できます(必要に応じて、中間ステップを経ずにcompile()単純に呼び出すこともできるようです。私が収集したものから、結果の構文をトラバースしたい場合に使用しますツリーをコンパイルする前に、ノードを検査し、場合によっては変更します。compile(some_string_containing_python_source, 'SomeName', 'exec')ast.parse()ast

最後に、実行名前空間で定義された関数、クラス、または変数を結果として得る前にexec()、結果を取得する必要があるようです。compile()

于 2013-04-14T09:38:38.417 に答える
0

pipeすべての文字列を python の子プロセスに入れて、そこから出力結果を取得するために使用できます。

グーグルos.popenまたはsubprocess.Popen

于 2013-04-14T09:03:39.677 に答える