python格式化显示复杂对象例如字典

当想格式化显示一个字典,并且希望通过日志记录输出时,Python 提供了几种方法来实现这一目标。这里有两种常用的方式来格式化显示字典内容:

1 使用 format 方法直接格式化

你可以直接使用 format 方法将字典转换为字符串,这种方法简单直接:

logger.info('self.para: {}'.format(self.para))

这种方法会打印出字典的完整内容,但如果字典很大或包含复杂的数据结构,输出可能会变得很难阅读。Python 的 format 方法提供了一种非常灵活的方式来构造字符串,但它本身不提供直接的机制来“美化”或“格式化显示”一个字典,如添加缩进或特定格式排版。format 主要用于插入数据到字符串中的特定位置,并支持一定程度的格式化,例如数字的格式化显示,但对于字典或列表这类复合数据结构的美化显示,format 方法的功能较为有限。

2 使用 json.dumps 来美化输出

使用 json.dumps 可以让字典的输出更加易读,尤其是对于嵌套较深或数据结构较复杂的字典。这个方法可以让你自定义缩进,从而使输出更加结构化:

import json
logger.info('self.para: {}'.format(json.dumps(self.para, indent=4)))

这里,indent=4 表示使用4个空格缩进,你可以根据需要调整缩进的大小。
json.dumps 需要所有的键和值都是JSON类型兼容的。
这意味着所有键必须是字符串类型,而值则需要是以下类型之一:

  • 字符串 (str)
  • 数字 (int, float)
  • 布尔值 (True, False)
  • 其他字典 (dict)
  • 列表 (list)
  • 元组 (tuple)
  • None

如果字典中包含不兼容的类型,如 Python 的 setdatetime 对象、或其他任何不是上述类型的对象,使用 json.dumps() 时将会引发 TypeError

假设我们有一个包含多种数据类型的字典:

import json
from datetime import datetime

# 创建一个包含多种数据类型的字典
data = {
    "name": "Alice",
    "age": 30,
    "birthday": datetime.now(),  # datetime 对象不是 JSON 兼容类型
    "education": ["BSc", "MSc"],
    "married": True,
    "children": None,
    "pets": {"dogs": 2, "cats": 1},
    "preferences": set([1, 2, 3])  # set 也不是 JSON 兼容类型
}

尝试使用 json.dumps() 来序列化这个字典:

try:
    json_str = json.dumps(data)
    print(json_str)
except TypeError as e:
    print(f"Error: {e}")

输出将会是一个错误信息,因为 datetimeset 类型不能被 json.dumps() 序列化。

解决方案

对于不兼容的类型,你需要在调用 json.dumps() 之前将它们转换为兼容的类型,或者提供一个自定义的序列化函数:

转换不兼容的类型

data['birthday'] = data['birthday'].isoformat()  # 将 datetime 转换为字符串
data['preferences'] = list(data['preferences'])  # 将 set 转换为 list
json_str = json.dumps(data)
print(json_str)

使用 default 参数提供自定义序列化函数

def json_custom_serializer(obj):
    if isinstance(obj, datetime):
        return obj.isoformat()
    elif isinstance(obj, set):
        return list(obj)
    raise TypeError(f"Type {type(obj)} not serializable")

json_str = json.dumps(data, default=json_custom_serializer)
print(json_str)

这样的处理确保了所有数据类型都可以被正确地序列化为 JSON 格式。

JSON(JavaScript Object Notation)最初是为 JavaScript 设计的一种数据交换格式。其设计目标是易于人类阅读和编写,同时也易于机器解析和生成。JSON 支持的数据类型有限,这是由其起源和设计目的决定的。以下是具体原因和考量:
JavaScript 兼容性:
JSON 的设计是基于 JavaScript 语言的对象字面量语法,因此它天然只支持那些在 JavaScript 中常见的数据类型。这包括了字符串、数字、布尔值、数组(在 JSON 中表现为列表)、对象(在 JSON 中表现为字典)以及 null(在 JSON 中表现为 None)。
跨语言交换数据:
JSON 被设计为一种语言独立的数据格式,目的是在不同编程语言和平台之间交换数据。支持的类型集团保持简单,可以确保在各种编程环境中都能无障碍地解析和生成,无论是 Python、Java、C# 等后端语言,还是 JavaScript 在前端的使用。
简洁性和易于实现:
JSON 的解析器和生成器可以相对简单地实现。限制数据类型有助于保持解析和生成过程的简洁性,降低实现的复杂度。这使得开发者能够轻松添加 JSON 支持到任何程序或服务中。
安全性:
避免复杂的数据类型如函数或执行代码,减少了安全风险。例如,与 XML 相比,JSON 没有支持执行代码的功能(如 XML 的实体和 CDATA 块可以用来嵌入代码),这减少了安全漏洞的风险。
序列化和反序列化的明确性:
限制数据类型确保在序列化(编码)和反序列化(解码)过程中,数据的表示是明确和一致的。例如,日期和时间在 JSON 中通常以 ISO 字符串格式表示,避免了关于时区和格式的混淆。

3 使用 pprint.pformat 来格式化打印

Python 的 pprint 模块提供了一个 pformat 函数,它可以生成一个格式化后的字符串表示形式,这对于复杂的数据结构尤其有用:

import pprint
logger.info('self.para: {}'.format(pprint.pformat(self.para, indent=4)))

json.dumps 类似,pprint.pformat 也允许你控制缩进,并能够更好地处理Python中的数据类型,比如 None, True, False 等。

4 自定义格式化函数

这个函数递归地处理字典,为每个嵌套的字典增加缩进,从而改善了字典的可读性。

def format_dict(d, indent=0):
    for key, value in d.items():
        if isinstance(value, dict):
            logger.info(' ' * indent + '{}: '.format(key))
            format_dict(value, indent + 4)
        else:
            logger.info(' ' * indent + '{}: {}'.format(key, value))

format_dict(self.para)

  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Python中可以使用str.format()方法来格式化输出字典。你可以通过在字符串中使用花括号{}来指定要替换的字段,然后使用format()方法传递字典作为参数来替换这些字段。例如,如果我们有一个字典person,包含name和age两个键值对,我们可以使用format()方法将它们插入到字符串中。代码示例如下: person = {'name': 'Eric', 'age': 17} print("Hello, {name}. You are {age} years old.".format(**person)) 运行结果为:Hello, Eric. You are 17 years old. [1] 另外,在Python 3.6及以上版本中,还可以使用f-Strings来进行格式化输出。f-Strings是一种更简洁、易读的格式化方法。你只需要在字符串前面加上字母f,并在花括号中写入要替换的变量名即可。代码示例如下: name = 'Eric' age = 17 print(f"Hello, {name}. You are {age} years old.") 运行结果为:Hello, Eric. You are 17 years old. [2] 使用str.format()方法和f-Strings都可以方便地对字典进行格式化输出,你可以根据自己的喜好和需求选择其中一种方法。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Python格式化输出](https://blog.csdn.net/kouyi5627/article/details/83246716)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值