[英]filter a variable such that its repr can be parsed by literal_eval
我想过滤一个变量(即删除无效内容),以便ast.literal_eval
可以解析其字符串表示ast.literal_eval
。 因此,基本上, filter_literal
函数可为任何obj
保证以下断言:
safe_obj = filter_literal(obj)
assert ast.literal_eval(repr(safe_obj))==safe_obj
我想出了以下功能,但是我对是否有更好的方法感兴趣,或者是否做错了任何事情,我很感兴趣:
_literal_types = set([type(None),bool,int,float,long,complex])
def filter_literal(obj, default=None):
""" return given `obj` with only "literal" types
The output can be safely converted to string and evaluated using
`ast.literal_eval`::
import ast
safe_obj = filter_literal(obj)
assert ast.literal_eval(repr(obj))==safe_obj
literal types are strings, number, tuples, lists, dicts, booleans and None
non-literal content are replaced by `default`
"""
obj_type = type(obj)
if obj_type in _literal_types:
return obj
elif isinstance(obj,dict):
return dict((k,filter_literal(v,default=default)) for k,v in obj.iteritems())
elif isinstance(obj,list):
return [filter_literal(v,default=default) for v in obj]
elif isinstance(obj,tuple):
return tuple([filter_literal(v,default=default) for v in obj])
else:
return default
一个明显的错误是您没有处理不是字典键的字符串:
>>> test = {"bar": [1, True, None, "foo"]}
>>> filter_literal(test)
{'bar': [1, True, None, None]}
您应该添加:
if isinstance(obj, basestring):
return obj
在确定您做错了什么方面, 测试一下您的功能 :
for test in [{"bar": [1, True, None, "foo"]}, ...]:
assert ast.literal_eval(repr(filter_literal(test))) == test
定义一些测试,并在进行更改时运行它。 另外,请注意,您可以简化递归调用,例如:
filter_literal(v, default)
我将在函数内部移动_literal_types
:
def filter_literal(obj, default=None):
"""docstring."""
_literal_types = set([type(None), bool, int, float, long, complex])
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.