5

(データベースからの)入力文字列を関数としてコンパイルして実行する必要があります。これは私が現在使用している方法です:

私はすでにこの関数を定義しているとしましょう:

def foo():
    print "Yo foo! I am a function!"

そして、データベースから読み込んだ文字列は、この関数を呼び出す必要があることを示しています。

string_from_db = "foo()"

次に、データベースから読み込んだ関数を返す関数(名前を制御できます)を作成します。

my_func_string = "def doTheFunc():\n\t return " + string_from_db

次に、文字列をコンパイルし、後で処理に使用する関数名に設定します。

exec my_func_string
processor = doTheFunc

私は後でそれを実行することによってそれを呼び出すことができますprocessor()Yo foo! I am a function!

私の質問:このコードの上にコメントがあります(長い間失われた開発者によって残されました):

    ###############################################################
    # The following method for getting a function out of the text #
    # in the database could potentially be replaced by using      #
    # Python's ast module to obtain an abstract syntax tree and   #
    # put it inside of a function node                            #
    ###############################################################

この「代替の可能性」についてもっと知りたいのですが。私はASTを調べましたが、上記のコードですでに行っていることを行うのにどのように役立つかについて非常に混乱しています。

  1. ASTを使用して同じことをどのように達成できますか?または、ASTはこのプロセスでどこで私を助けることができますか?
  2. ASTを使用した実装の方が優れていますか?その理由は何ですか?
4

1 に答える 1

5

ASTは、悪意のある命令を含む可能性のある、evalまたはexec任意の式を実行できる信頼できないコードを評価する場合にはるかに安全な選択です。一方、ASTを使用すると、式を自分で解析および検証したり、次ast.literal_evalのようなものを使用して限定された式を実行したりできます。文字列、リスト、数字、その他いくつかのものだけを許可するサンドボックス。これは単純な例です。

import ast
a = ast.literal_eval("[1,2,3,4]") //evaluate an expression safely.

文字列をASTに解析する別の例:

import ast
source = '2 + 2'
node = ast.parse(source, mode='eval')
ast.dump(node)

これは印刷します:

Expression(body=BinOp(left=Num(n=2), op=Add(), right=Num(n=2)))

ここには非常に優れたチュートリアルとドキュメントがあります

于 2012-11-12T19:24:28.363 に答える