繁体   English   中英

Python 打印 !!python/object 当 class 被调用时

[英]Python print !!python/object when class is called

我在运行脚本时遇到了一个奇怪的问题。 基本上,我只想将 json 转换为 yaml 并将结果放入文件中。 当我运行以下代码时:

#!/usr/bin/env python3
from CP import test
import json, yaml

dump_value = {"objects": [{"name": "home_pc","ipv4": "1.1.1.1"},{"name": "home_switch","ipv4": "1.1.1.10"},{"name": "dns_server","ipv4": "8.8.8.8"}]}

# Initialize dict
cpdb = test.db_utils()

cpdb.create_list("hosts")
for h in dump_value['objects']:
    cpdb.add_listdata("hosts", json.dumps({"name": h['name'], "ipv4": h['ipv4']}))

print(yaml.dump(cpdb, indent=2, default_flow_style=False, sort_keys=False))

output 是:

!!python/object:CP.test.db_utils
data:
  top:
    hosts:
    - '{"name": "home_pc", "ipv4": "1.1.1.1"}'
    - '{"name": "home_switch", "ipv4": "1.1.1.10"}'
    - '{"name": "dns_server", "ipv4": "8.8.8.8"}'

下面是 CP 中 test.py 的内容:

#!/usr/bin/env python3

class db_utils:
    def __init__(self):
        self.data = {}
        self.data['top'] = {}

    def create_list(self, key): self.data['top'][key] = []
    def add_data(self, key, value): self.data['top'][key] = value
    def add_listdata(self, key, value): self.data['top'][key].append(value)

我预计以下 output:

top:
  hosts:
  - '{"name": "home_pc", "ipv4": "1.1.1.1"}'
  - '{"name": "home_switch", "ipv4": "1.1.1.10"}'
  - '{"name": "dns_server", "ipv4": "8.8.8.8"}'

我使用 python 3.8.3。 我已经在另一台计算机上尝试过代码(想也许我弄坏了一些东西),但在 python 3.9.1 上的结果相同。

我认为它可能与 test.py 中的 class db_utils 有关,但我找不到问题所在。

先感谢您 !

您得到 output 的原因是您正在转储您直接创建的prdb object,其数据结构包含一个名为data的顶级字典。

另一个问题,您看到的第一行指定了您正在转储的 object 的类型,出于类似的原因出现。 它存在是因为您没有转储标准 Python 结构,而是转储任意 class 实例。 Yaml 转储 header 以指示 class 被转储,这样当您读取 Z944463F395E3Z 文件时,您就有机会重新构建它。

要解决这两个问题,您应该只提取您想要由 YAML 表示的原始数据结构并将其转储。 为此,您可以向db_utils object 添加一个方法,该方法返回其data属性的内容。 然后你可以转储它。 这是添加和使用get_data方法的代码(为方便起见,您的两个文件合并为一个):

#!/usr/bin/env python3
import json, yaml

class db_utils:
    def __init__(self):
        self.data = {}
        self.data['top'] = {}

    def create_list(self, key): self.data['top'][key] = []

    def add_data(self, key, value): self.data['top'][key] = value

    def add_listdata(self, key, value): self.data['top'][key].append(value)

    def get_data(self): return self.data

dump_value = {"objects": [{"name": "home_pc","ipv4": "1.1.1.1"},{"name": "home_switch","ipv4": "1.1.1.10"},{"name": "dns_server","ipv4": "8.8.8.8"}]}

# Initialize dict
cpdb = db_utils()

cpdb.create_list("hosts")
for h in dump_value['objects']:
    cpdb.add_listdata("hosts", json.dumps({"name": h['name'], "ipv4": h['ipv4']}))

print(yaml.dump(cpdb.get_data(), indent=2, default_flow_style=False, sort_keys=False))

结果:

top:
  hosts:
  - '{"name": "home_pc", "ipv4": "1.1.1.1"}'
  - '{"name": "home_switch", "ipv4": "1.1.1.10"}'
  - '{"name": "dns_server", "ipv4": "8.8.8.8"}'

您甚至不必将额外的方法添加到db_utils 您可以直接从 object 中获取data属性。 我认为添加一种获取内部数据的方法会更简洁,但是如果您想要更小的更改(添加 5 个字符),只需将代码的最后一行更改为:

print(yaml.dump(cpdb.data, indent=2, default_flow_style=False, sort_keys=False))

你得到的结果是一样的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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