2011-01-10 7 views
1

私は、後で実行するためにdbに格納されたタスクをいくつか持っています。たとえば、私は電子メールを送信するタスクを修正することができます。そして、cron execタスク(send it)を実行します。後で実行するためのコードをdbに格納する最良の方法を探します。ジャンゴから後で実行するためのコードを格納する最善の方法(Python)

のS =」:Pythonコードの生の文字列内と比べて、それが元ストアの場合はevalんが、また、私はここに相対輸入を格納する必要があります。..

例えばメールを送るために私はこのような文字列を修正する必要があります.core.mail import send_mail \ n send_mail( 'subj'、 'body'、 '[email protected]'、['[email protected]']、fail_silently = False) "

以降eval。このような仕事のために最良の方法でやるか、よりよいパターンを作るためのアイデアですか?

答えて

4

あなたがやっていることは、主に実行されるコードのバラツキが大きすぎるためです。コード文字列は何かを行うことができます。後で実行するために保存したいタスクはいくつかあります。

これらのタスクの変数はどのようなものか(非プログラミングの意味の変数:変化するもの)を把握し、関数の引数のタプルやキーワード引数の辞書既知の関数に適用されます。

もっと派手なことに、何らかの種類のコンテナオブジェクトをその上にいくつか持っていて、その引数とともに呼び出す関数の名前を格納することができます。そのコンテナは、例のようにDjangoのsend_mailのような関数をインポートするモジュールのような単純なものにすることができます。

func = 'send_mail' 
args = ('subj', 'body', '[email protected]', ['[email protected]']) 
kwargs = {'fail_silently': False} 

my_call = cPickle.dumps((func, args, kwargs)) 

そして、このようにそれを使用します:

func, args, kwargs = cPickle.loads(my_call) 

getattr(my_module, func)(*args, **kwargs) 
+0

美しい、pythonic。驚くばかり。 –

2

このソリューションはまったく使用しません。私は各タスク(メールの送信、ファイルの削除など)ごとに異なるハンドラを作成します。この方法でコードを保存するのは面倒です。

EDIT

の例では、ハンドラの独自の書式を作成することになります。たとえば、次の形式の各行のハンドラは、次のようになります。

handlername;arg1;arg2;arg3;arg4 

次に、行を読み込んで解析するためにpythonを使用します。

sendmail;[email protected];subject;body 

このように解析されます:たとえばこれは、格納されたラインになり

for line in database: 
    handler, *args = line.split(";") 
    if handler == "sendmail": 
     recipient, subject, body, = args[:3] 
     # do stuff 
    elif handler == "delfile": 
     #etc 
+1

-1:あなたはしないだろうことは非常に興味深いものではありません

次に、あなたの例では、このように呼んで保存することができます。悪い考え方がたくさんあります。 *より良いアイデアは何ですか?彼らが使うことができる解決策は何でしょうか? –

+0

アイデアを提案しました。 *「各タスク(メールの送信、ファイルの削除など)ごとに異なるハンドラを作成します」* – orlp

+0

ここに私の主張があります。投稿を修正して、あなたが何をやるのかがはっきりしているでしょうか?私たちの中には、役に立たないコメントよりも少ない括弧で囲まれているので、私たちの中には、この提案を見逃した人がいましたそして、「別のハンドラを作成する」ということを少し増幅することができますか?これは良いアイデアかもしれないように聞こえる。それ以外は要約されている。 –

1

私はあなたがディスパッチャで任意のコードを触れるにせずにハンドラを追加するための柔軟性の両方を持つことができ、このように論理的なコマンドを格納し、

def run_command(cmd): 
    fields = map(unescape, cmd.split(";")) 
    handlers[fields[0]](fields[1:]) 

... 

@handler("mail") 
def mail_handler(address, template): 
    import whatever 
    ... 
    send_mail(address, get_template(template) % user_info, ...) 

のようなものでそれらをexecしたいとまだデータベースのコードの詳細を書いているわけではないので、検査や統計を行うのが難しくなります。

0

あなたの質問に直接答えるために、evalは実際にの結果をもたらすコードを評価するためだけです。例:あなたは、単に数行のコードはおそらく、コードを実行したい場合は

>>> eval('1 + 1') 
2 

はしかし、あなたは(EXECたい)、デフォルトでは、発信者の名前空間内で実行する:

>>> exec("x = 5 + 5") 
>>> print x 
10 

注意だけで信頼できるコードはexecかevalのどちらかに渡されるべきです。ファイルを実行するにはexecfileも参照してください。

他にも、任意のコードを格納するのではなく、やりたいことを問題にする方法を見つけるべきだと私は同意します。たとえば、次のようなことができます。

def myMailCommand(...): 
    ... 

def myOtherCommand(...): 
    ... 

available_commands = {'mail': myMailCommand, 
         'other': myOtherCommand} 

to_execute = [('mail', (arg1, arg2, arg3)), 
       ('other', (arg1, arg2))] 

for cmd, args in to_execute: 
    available_commands[cmd](*args) 

上記の疑似コードでは、2つの方法を定義しました。それから私はコマンドにアクションをマッピングする辞書を持っています。次に、アクションと引数のデータ構造を調べ、それに応じて適切な引数を呼び出します。あなたはその考えを得る。

関連する問題