我有一个数据库,其中包含Python函数的名称和代码的字符串。我希望用户能够输入Python代码并查看结果。问题是我需要知道他们调用的函数的名称,以便从数据库中检索代码。例如,如果他们输入cubic_fit(1, 2, get_data())
,我需要一种方法来获取函数名称cubic_fit
和get_data
。有没有办法做到这一点?
答案 0 :(得分:11)
内置函数compile将完全为您完成:
>>> compile("cubic_fit(1, 2, get_data())", '<string>', 'eval').co_names
('cubic_fit', 'get_data')
运行安全。没有代码实际上只是被编译。
答案 1 :(得分:2)
你开始的一个简单例子。请注意,为了实现这一点,您将期望有效的python语义。
您可以扩展它以解析您的参数......
import token, tokenize, StringIO
def extract_names(src):
rawstr = StringIO.StringIO(unicode(src))
tokens = tokenize.generate_tokens(rawstr.readline)
for i, item in enumerate(tokens):
toktype, toktext, (srow,scol), (erow,ecol), line = item
if token.tok_name[toktype] == 'NAME':
print 'name:', toktext
extract_names("cubic_fit(1, 2, get_data())")
# --> output:
# name: cubic_fit
# name: get_data
答案 2 :(得分:0)
如果您只想要名称,那么compile()和co_names方法将最有效。
您还可以利用eval()的功能将任何映射对象用作其locals参数。您可以创建一个映射对象,以便根据需要在eval()中查找和编译数据库中的对象。
示例:
class LookitUp(object):
def __init__(self):
# simulate some data
self.d = { "foo": "def foo(a):\n return a + 2"}
def __getitem__(self,key):
localdict = {}
c = compile(self.d.get(key,""),"<string>","exec")
eval(c,globals(),localdict)
return localdict[key]
d = LookitUp()
def bar(a):
return a - 1
print "foo from database :",eval("foo(3)",globals(), d)
print "bar from globals():",eval("bar(3)",globals(), d)
print "foo(bar(3)) :",eval("foo(bar(3))",globals(), d)
结果:
foo from database : 5
bar from globals(): 2
foo(bar(3)) : 4
您可能需要根据数据库中的来源进行修改,但这是一个可以开始的地方。