我正在尝试开发一个模块,它将自动将我的参数转换为python对象并创建一个带参数和对象的字典。如果模块找到@ name @给出的参数名称,则必须替换参数值。导入模块中生成的嵌套lambda函数失败
这里的代码和一个例子在最后。
#FILE convertor.py
import types
is_lambda = lambda value : isinstance(value, types.LambdaType) and value.__name__ == '<lambda>'
def builder(tree, target, item, delimiter):
if delimiter not in item:
return item
result = ''
copir = item.split(delimiter)
for prefix,var in map(None,copir[::2],copir[1::2]):
if prefix is not None: result += prefix
if var is None: continue
lmdcheck = is_lambda(tree[var])
if lmdcheck or delimiter is '@':
result += target+"[\""+var+"\"]"
elif delimiter is '$':
result += str(tree[var])
else:
return None
return result
def resolve_name(tree, target, item):
"""
Resolves links and string in RHS of parameters
"""
# Resolve links First
result = ''
bld = builder(tree, target, item , '@')
if bld is None: return None
result = bld
# And then Resolve strings
bld = builder(tree, target, result, '$')
if bld is None: return None
result = bld
return unicode(result)
def generate(params, target, parent=None):
"""
@function generate generate recods in root initial directory
@param params - list of (name, value) records
@param target - string of variable name which will be generate (need for lambda(s)),
@param parent - methodtree object which will be updated
"""
if parent is None:
try:
exec target+"= {}"
except BaseException as e:
self.error("Cannot create target object self.{}: {}".format(target,e),"generate")
return None
else:
try:
exec target+"= parent"
except BaseException as e:
self.error("Cannot create target object self.{}=parent: {}".format(target,e),"generate")
return None
try:
exec "tree = "+target
except BaseException as e:
error("Cannot create temporal variable tree for return target object:".format(e),"generate")
for name, value in params:
value = resolve_name(tree, target,value)
try:
exec "{}[\'{}\']={}".format(target,name,value)
except BaseException as e:
error("Cannot execute operation self.{}[\'{}\']={}: {}".format(target,name,value,e),"generate")
return None
return tree
if __name__ == "__main__":
params=[
['parameter', '3'],
['Varibale X','5'],
['Pwered X','@Varibale [email protected]**@[email protected]'],
['FunctionA','lambda x,p:x**p'],
['FunctionB', 'lambda k:@[email protected](k,$parameter$)']
]
dic = generate(params,'dic')
for n in dic:
print n, dic[n], type(dic[n])
if n == 'FunctionA':
print "FunctionA:", dic[n](2,3)
if n == 'FunctionB':
print "FunctionB:", dic[n](2)
所以一切都很好地工作,如果我运行python convertor.py
$ python convertor.py
FunctionA <function <lambda> at 0x7ff116246848> <type 'function'>
FunctionA: 8
Varibale X 5 <type 'int'>
FunctionB <function <lambda> at 0x7ff1162468c0> <type 'function'>
FunctionB: 8
parameter 3 <type 'int'>
Pwered X 125 <type 'int'>
然而,当我输入从我convertor.py产生,在嵌套lambda功能不起作用。
#File test.py
from convertor import generate
params=[
['FunctionA','lambda x,p:x**p'],
['parameter', '3'],
['FunctionB', 'lambda k:@[email protected](k,$parameter$)']
]
dic = generate(params,'dic')
for n in dic:
print n, dic[n], type(dic[n])
if n == 'FunctionA':
print "FunctionA:", dic[n](2,3)
if n == 'FunctionB':
print "FunctionB:", dic[n](2)
FunctionA <function <lambda> at 0x7fe037994848> <type 'function'>
FunctionA: 8
FunctionB <function <lambda> at 0x7fe0379948c0> <type 'function'>
FunctionB:
Traceback (most recent call last):
File "runner.py", line 14, in <module>
print "FunctionB:", dic[n](2)
File "<string>", line 1, in <lambda>
NameError: global name 'dic' is not defined
我在SO中找不到任何相似的主题,但它可能是重复的。
我可能明白为什么会发生这种情况。我只是想知道有没有解决方案?
所以它会是'generate(.... context = globals())'并且在生成它的时候'exec ..在上下文中。这是对的吗? – rth
应该是这样的。我没有真正尝试过你的代码,并且实际上不太了解它,以确保这不会导致其他问题。 – jasonharper
谢谢,它似乎工作。好答案! – rth