Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
围绕python开展工作';s json模块不喜欢循环引用_Python_Json - Fatal编程技术网

围绕python开展工作';s json模块不喜欢循环引用

围绕python开展工作';s json模块不喜欢循环引用,python,json,Python,Json,除了使用外部库(比如可能,尽管我没有尝试过),还有没有办法让python的json模块dump一个具有循环引用(即删除引用)的字典(或列表等) 我只想使用json更容易地查看一些调试输出。好吧,除了标准模块之外,这里有一个解决方案,它利用repr来处理循环引用。编辑:有关最新版本,请参见 #MAGIC-NUMBER:max length只是一个合理大小的猜测,例如80 cols x 100行 def dump(值,msg='dump',max_length=80*100,stdout=False

除了使用外部库(比如可能,尽管我没有尝试过),还有没有办法让python的
json
模块
dump
一个具有循环引用(即删除引用)的字典(或列表等)


我只想使用json更容易地查看一些调试输出。

好吧,除了标准模块之外,这里有一个解决方案,它利用
repr
来处理循环引用。编辑:有关最新版本,请参见

#MAGIC-NUMBER:max length只是一个合理大小的猜测,例如80 cols x 100行
def dump(值,msg='dump',max_length=80*100,stdout=False,pick=None):
"""
将尽可能详细的值描述写入logging.DEBUG。
看见http://stackoverflow.com/q/27830888/116891
:param value:感兴趣的项目。
:类型值:对象
:param msg:记录项的前缀(默认值为'DUMP')
:type msg:basestring
:param max_length:允许的最长字符串长度(设置为“无”表示无限制)
:键入最大长度:int
:param stdout:如果为true,则打印而不是记录(默认值=False)
:类型stdout:bool
:param pick:如果指定,则仅转储项目的这些键的值
(值必须是dict或allow _dict __访问)。
这个名字来自http://underscorejs.org/#pick.
:type pick:iterable of basestring
:return:如果消息被转储,则返回True
:rtype:bool
"""
如果不是logging.getLogger().isEnabledFor(logging.DEBUG)而不是stdout:
返回
如果选择:
d=存在(值,dict)时的值,否则为值。\u dict__
过滤={
物业名称:d[物业名称]
对于拾取中的属性名称
如果属性名称在d中
}
值=已过滤
kwargs=dict(缩进=2,排序键=True)
尝试:
导入json
info=json.dumps(值,**kwargs)
除:
#JSON不喜欢循环引用:/
尝试:
字符串_repr=repr(值)
#替换python原语、单引号、unicode等
string_repr=string_repr\
.replace('None','null')\
.replace('True','True'))\
.replace('False','False'))\
.替换(“u“,”))\
.替换(“'”,“'”)
#替换对象和函数repr的类似项
string_repr=re.sub(r':(\s+)(]+>)',r':\1“\2”',string_repr)
#用列表替换元组,非常天真
string_repr=string_repr.replace('(','[')。replace('),']'))
info=json.dumps(json.loads(string_repr),**kwargs)
除:
从pprint导入pformat
信息=P格式(值,缩进=2)
定义输出(格式化字符串,*格式化参数):
“”“格式化字符串并将其输出到正确的位置。”“”
如果标准输出:
打印(格式化字符串%format参数)
其他:
调试(格式化的字符串,*格式化的参数)

如果“最大长度”为“无”或“长度”(信息)不要只做
,除了:
这会捕获系统异常。是的,我知道。我很懒。虽然,如果有系统异常,它很可能会在最后的except子句中被重新引发。这不是用于生产日志;)哈!所以我没有任何评论就被否决了。有时我认为人们对编码的回答过于个人化了!为什么你想避免另一个库吗?你可以使用YAML,我很确定它可以处理循环引用。在我的例子中,我在google app engine中运行,不包含外部库更容易(除非它提供了很多价值).但我相信其他人有不同的原因。链接到其他LIB当然有帮助,但这不是主要问题。
# MAGIC-NUMBER: max length is just some guess at a reasonable size, e.g. 80 cols by 100 lines
def dump(value, msg='DUMP', max_length=80 * 100, stdout=False, pick=None):
    """
    Write as verbose of a description of the value as possible to logging.DEBUG.

    See http://stackoverflow.com/q/27830888/116891

    :param value: The item of interest.
    :type value: object
    :param msg: Prefix for the logged item (default='DUMP')
    :type msg: basestring
    :param max_length: Longest allowed string length (set to None for unlimited)
    :type max_length: int
    :param stdout: If true, print instead of logging (default=False)
    :type stdout: bool
    :param pick: If specified, dump only values for these keys of the item
        (value must be a dict or allow __dict__ access).
        The name comes from http://underscorejs.org/#pick.
    :type pick: iterable of basestring
    :return: True if message dumped
    :rtype: bool
    """
    if not logging.getLogger().isEnabledFor(logging.DEBUG) and not stdout:
        return

    if pick:
        d = value if isinstance(value, dict) else value.__dict__
        filtered = {
            property_name: d[property_name]
            for property_name in pick
            if property_name in d
        }
        value = filtered

    kwargs = dict(indent=2, sort_keys=True)
    try:
        import json
        info = json.dumps(value, **kwargs)
    except:
        # JSON doesn't like circular references :/
        try:
            string_repr = repr(value)
            # Replace python primitives, single-quotes, unicode, etc
            string_repr = string_repr\
                .replace('None', 'null')\
                .replace('True', 'true')\
                .replace('False', 'false')\
                .replace("u'", "'")\
                .replace("'", '"')

            # Replace object and function repr's like <MyObject ...>
            string_repr = re.sub(r':(\s+)(<[^>]+>)', r':\1"\2"', string_repr)

            # Replace tuples with lists, very naively
            string_repr = string_repr.replace('(', '[').replace(')', ']')

            info = json.dumps(json.loads(string_repr), **kwargs)
        except:
            from pprint import pformat
            info = pformat(value, indent=2)

    def _out(formatted_string, *format_args):
        """Format the string and output it to the correct location."""
        if stdout:
            print(formatted_string % format_args)
        else:
            logging.debug(formatted_string, *format_args)

    if max_length is None or len(info) <= max_length:
        _out('%s: %s', msg, info)
        return True
    else:
        _out(
            'Did not dump "%s" due to length restriction. Increase max_length if desired.', msg
        )
    return False