我想在 python 中构建一个类,它支持从用户提供的源代码动态更新方法。
类的实例Agent
有一个方法go
。在构造实例时,它的.go()
方法什么也不做。例如,如果我们这样做a=Agent()
,那么a.go()
我们应该得到 aNotImplementedError
或类似的东西。然后,用户应该能够a.go()
通过提供源代码进行交互定义。一个简单的源代码示例是
我的来源字符串 ="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 中工作)