繁体   English   中英

过滤变量,以便其repr可以由literal_eval解析

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM