12

質問: Python で文字列を使用して関数オブジェクトを作成する方法はありますか?


情報: sqlite3 サーバー バックエンドにデータを保存するプロジェクトに取り組んでいます。それについて夢中になることは何もありません。コードは信じられないほどありふれたものであるため、DAL クラスはコード生成によって行われることが非常に一般的です。しかし、それは私に考えを与えました。Python で属性が見つからない場合、関数を定義する__getattr__と、エラーになる前にそれが呼び出されます。そのため、パーサーとロジック ツリーを使用して、最初の呼び出しで必要なコードを動的に生成し、関数オブジェクトをローカル属性として保存することができました。例えば:

DAL.getAll()

#getAll() not found, call __getattr__

DAL.__getattr__(self,attrib)#in this case attrib = getAll

##parser logic magic takes place here and I end up with a string for a new function

##convert string to function

DAL.getAll = newFunc

return newFunc

コンパイル機能を試してみましたが、この種の偉業を達成できるという点では、exec と eval は満足のいくものではありません。複数行の機能を許可するものが必要です。ディスクへの書き込みを伴わない方法以外に、これを行う別の方法はありますか? 繰り返しますが、関数オブジェクトを動的に作成しようとしています。

PS: はい、セキュリティと安定性に恐ろしい問題があることは承知しています。はい、私はこれが恐ろしく非効率的な方法であることを知っています。だから?番号。これは概念実証です。「Python はこれを実行できますか?関数オブジェクトを動的に作成できますか?」私が知りたいのは、優れた代替案ではありません。(ただし、目前の質問に答えた後は、より優れた代替案に自由に取り組んでください)

4

3 に答える 3

26

以下は、文字列で定義した記号を辞書に入れますd

d = {}
exec "def f(x): return x" in d

これd['f']が関数オブジェクトです。文字列のコードでプログラムの変数を使用する場合は、次の方法で送信できますd

d = {'a':7}
exec "def f(x): return x + a" in d

ここで、d['f']は動的ににバインドされる関数オブジェクトですd['a']。を変更d['a']すると、の出力も変更されますd['f']()

于 2011-05-23T14:38:55.390 に答える
2

このようなことはできませんか?

>>> def func_builder(name):
...  def f():
...   # multiline code here, using name, and using the logic you have
...   return name
...  return f
... 
>>> func_builder("ciao")()
'ciao'

基本的に、文字列をアセンブルしてから関数にコンパイルしようとするのではなく、実際の関数をアセンブルします。

于 2011-05-23T14:43:33.873 に答える
0

単純に概念の証明である場合は、eval と exec で問題ありません。pickle 文字列、yaml 文字列、およびコンストラクターを作成することを決定した他のものでもこれを行うことができます。

于 2011-05-23T13:49:45.830 に答える