ユーザー提供のソースコードからのメソッドの動的更新をサポートするクラスをPythonで構築したいと思います。
クラスのインスタンスにはAgent
メソッドがありgo
ます。インスタンスが構築される時点では、その.go()
メソッドは何もしません。たとえば、 を実行するa=Agent()
と、 またはそのようなものa.go()
を取得する必要がありNotImplementedError
ます。a.go()
ユーザーは、ソース コードを提供することにより、対話的に定義できる必要があります。簡単なソース コードの例は次のようになります。
mySourceString ="print('I learned how to go!')"
a
このよう
に注入されますa.update(mySourceString)
a.go()
をさらに呼び出すと"I learned how to go!"
、画面に出力されます。
次のコードでこれを行う方法を部分的に理解しました。
import types
class Error(Exception):
"""Base class for exceptions in this module."""
pass
class NotImplementedError(Error):
pass
class Agent(object):
def go(self):
raise NotImplementedError()
def update(self,codeString):
#Indent each line of user supplied code
codeString = codeString.replace('\n','\n ')
#Turn code into a function called func
exec "def func(self):\n"+' '+codeString
#Make func a bound method on this instance
self.go = types.MethodType(func, self)
質問
- この実装は賢明ですか?
- この実装により、予期しないスコープの問題が発生しますか?
- ユーザーが提供したコードをサンドボックス化して、外部オブジェクトに触れないようにする明確な方法はありますか? 許可された外部オブジェクトのセットを提供することでこれを行う方法を考えることができますが、これは Pythonic ではないようです。
おそらく役に立つ SO 投稿
(私はpython 2.6で作業しています)