我想做类似的事情:
import ast
def foo(common_stuff, assignment_str):
common_stuff()
ast.literal_eval(assignment_str) # assignment to unknown or passed variable
foo('a=1;b=2')
这在Python中可能吗?
我正在尝试为此执行一般功能(强制执行DRY):
for f, i in zip(task_set, xrange(len(task_set))):
cd = f.cleaned_data
t_name = cd.get('t_name')
start_date = cd.get('start_date')
end_date = cd.get('end_date')
project = Project.objects.get(pro_id=p.pro_id)
task = Task(t_name=t_name, start_date=start_date,
end_date=end_date, project=project)
task.save()
tasks_list.append(task)
所以我开始编写以下内容:
def save_form(model, formset, foreignkey_assignment, *args){
for f, i in zip(formset, xrange(len(formset))):
cd = f.cleaned_data
get_key_name = lambda x: cd.get(x)
ast.literal_eval(foreignkey_assignment)
m = model(**{k:get_key_name(k) for k in args})
m.save()
}
答案 0 :(得分:3)
ast.literal_eval()
'执行'评估的AST解析树,并将其限制为仅允许标准Python文字的严格子集。您可以使用source code并添加分配支持(我在其中使用单独的字典来处理名称)。
您必须添加Assign
和Name
节点处理(Python 3版本):
def literal_eval(node_or_string, namespace):
"""
Safely evaluate an expression node or a string containing a Python
expression. The string or node provided may only consist of the following
Python literal structures: strings, bytes, numbers, tuples, lists, dicts,
sets, booleans, and None.
"""
if isinstance(node_or_string, str):
node_or_string = ast.parse(node_or_string, mode='exec')
if isinstance(node_or_string, ast.Module):
node_or_string = node_or_string.body
def _convert(node, ns=None):
if isinstance(node, (ast.Str, ast.Bytes)):
return node.s
elif isinstance(node, ast.Num):
return node.n
elif isinstance(node, ast.Tuple):
return tuple(map(_convert, node.elts))
elif isinstance(node, ast.List):
return list(map(_convert, node.elts))
elif isinstance(node, ast.Set):
return set(map(_convert, node.elts))
elif isinstance(node, ast.Dict):
return dict((_convert(k), _convert(v)) for k, v
in zip(node.keys, node.values))
elif isinstance(node, ast.NameConstant):
return node.value
elif isinstance(node, ast.UnaryOp) and \
isinstance(node.op, (ast.UAdd, ast.USub)) and \
isinstance(node.operand, (ast.Num, ast.UnaryOp, ast.BinOp)):
operand = _convert(node.operand)
if isinstance(node.op, ast.UAdd):
return + operand
else:
return - operand
elif isinstance(node, ast.BinOp) and \
isinstance(node.op, (ast.Add, ast.Sub)) and \
isinstance(node.right, (ast.Num, ast.UnaryOp, ast.BinOp)) and \
isinstance(node.left, (ast.Num, ast.UnaryOp, ast.BinOp)):
left = _convert(node.left)
right = _convert(node.right)
if isinstance(node.op, ast.Add):
return left + right
else:
return left - right
elif isinstance(node, ast.Assign) and \
len(node.targets) == 1 and \
isinstance(node.targets[0], ast.Name):
assert isinstance(ns, dict) # will be None when not top-level
ns[node.targets[0].id] = _convert(node.value)
return
raise ValueError('malformed node or string: ' + repr(node))
return _convert(node_or_string, namespace)
或者您可以使用asteval
project,它使用AST树解释来支持简单的表达式和赋值。
答案 1 :(得分:0)