我正在嘗試開發一個模塊,它將自動將我的參數轉換爲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