获取Python表达式中调用的函数

时间:2009-11-12 23:54:52

标签: python

我有一个数据库,其中包含Python函数的名称和代码的字符串。我希望用户能够输入Python代码并查看结果。问题是我需要知道他们调用的函数的名称,以便从数据库中检索代码。例如,如果他们输入cubic_fit(1, 2, get_data()),我需要一种方法来获取函数名称cubic_fitget_data。有没有办法做到这一点?

3 个答案:

答案 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

您可能需要根据数据库中的来源进行修改,但这是一个可以开始的地方。