2012-11-12 6 views
5

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

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を使用した実装が優れているのはなぜですか?
+5

あなたは暗い魔法の領域にいます。 –

+1

文字列が安全であると分かっているなら、 'ast'を' exec() 'に使う理由はありません。 PythonインタプリタはすでにPythonのソースコードを関数オブジェクトに解析して実装しています。なぜそれを複製するのですか? – millimoose

+0

@millimoose私は文字列が安全であることを知っているので、私は 'exec'実装に行きました。しかし、この質問は「ast」のより良い使用について私に啓発している。ありがとう! – dinkelk

答えて

5

一方ASTは、あなたが解析し、検証表現を自分で、または実行することを可能にしながら、ASTは、悪意のある命令を含むことができ、信頼できないコードを評価する際、evalまたはexecは任意の式を実行することができ、より安全な選択肢です文字列、リスト、数字、および他のいくつかのものだけを許可するサンドボックスのような種類の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))) 

も非常に良いチュートリアルhereとありますdocumentation

+0

偉大なチュートリアル!私はどのように "自分自身のために表現を検証する"に行くだろうか?コードが悪いのか、自分の要件を満たしていないのかをどうやって知ることができますか?小さな関数をコンパイルする必要があると仮定します。私は自分自身を単純な文字列、リストなどに限定することはできません。 – dinkelk

+0

@babydanksあなたは 'open'のように、そうしてはいけない関数を呼び出すかどうかを知ることができます。 – iabdalkader

+0

ああ!これは一番簡単ですか?一度あなたはast関数ノードを持っていますか? (すなわち、 'open'をチェックする最も簡単な方法は何ですか?) – dinkelk

関連する問題