英文:
How to dump a string read from a text file into a YAML file without single quotes
问题
我有一个字符串,它是一个32字节的`.hex`文件的哈希值。它的格式是 `0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075`。我必须从一个文本文件中读取这个字符串,然后将它转储到yaml文件中,而不带有任何单引号。
我在Python中编写的程序是:
import yaml
# 指定输入文件的路径
input_file_path = 'output.txt'
# 从输入文件中读取值
with open(input_file_path, 'r') as input_file:
value = input_file.read().strip()
with open('temp.yaml', 'r') as file:
yaml_data = yaml.safe_load(file)
yaml_data['DataSecurityContainer']['items'][0] = value
with open('temp.yaml', 'w') as file:
yaml.dump(yaml_data, file, default_style=None)
期望的yaml文件输出:
DataSecurityContainer:
items:
- 0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075
实际的yaml文件输出:
DataSecurityContainer:
items:
- '0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075'
我尝试了所有可能的方法来删除这个单引号,但它没有正常工作。如果有人能告诉我这里的错误是什么,我会很感激的。
英文:
I have a string which is a 32-byte hash of a .hex
file. It is of the format 0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075
. I have to read this string from a text file and dump it into yaml file without any single quotes.
The program I have written in Python is :
import yaml
# Specify the file path for the input file
input_file_path = 'output.txt'
# Read the value from the input file
with open(input_file_path, 'r') as input_file:
value = input_file.read().strip()
with open('temp.yaml', 'r') as file:
yaml_data = yaml.safe_load(file)
yaml_data['DataSecurityContainer']['items'][0] = value
with open('temp.yaml', 'w') as file:
yaml.dump(yaml_data, file, default_style=None)
Expected outcome in yaml file :
DataSecurityContainer:
items:
- 0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075
Actual outcome in yaml file:
DataSecurityContainer:
items:
- '0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075'
I have tried all possible ways to remove this single quotes but it is not working correctly. Appreciate it if someone could let me know what is the mistake here
答案1
得分: 1
将您的值包装在一个具有自定义表示器的类中。最小示例:
import yaml, sys
class AsHex(str):
pass
def represent_hex(dumper, data):
return dumper.represent_scalar("tag:yaml.org,2002:int", data, style="")
yaml.add_representer(AsHex, represent_hex)
yaml.dump({"test": AsHex("0xdeadbeef")}, sys.stdout)
输出:
test: 0xdeadbeef
我们必须生成一个带有!!int
标签的标量(这是我们使用的完整形式的简写),因为PyYAML只有在识别到加载值将分配相同标签给它时才会写出不带引号的值。由于您的值是十六进制整数,加载时将为其分配!!int
标签,因此我们必须告诉PyYAML,我们生成的标量表示一个!!int
。
英文:
Wrap your value in a class with a custom representer. Minimal example:
import yaml, sys
class AsHex(str):
pass
def represent_hex(dumper, data):
return dumper.represent_scalar("tag:yaml.org,2002:int", data, style="")
yaml.add_representer(AsHex, represent_hex)
yaml.dump({"test": AsHex("0xdeadbeef")}, sys.stdout)
output:
test: 0xdeadbeef
We must generate a scalar with !!int
tag (which is a shorthand for the complete form we use) because PyYAML only writes the value without quotes if it recognizes that loading the value will assign the same tag to it. Since your value is a hexadecimal integer, loading will assign the !!int
tag to it, so we must tell PyYAML that the scalar we generate represents an !!int
.
答案2
得分: 0
我建议你升级到我的 ruamel.yaml
。它支持YAML 1.2,可以保留注释、标签等,包括整数的格式:
import sys
import ruamel.yaml
yaml_str = """\
DataSecurityContainer:
items:
- 0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075 # 作为整数子类加载的标量
"""
yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)
输出结果:
DataSecurityContainer:
items:
- 0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075 # 作为整数子类加载的标量
如果你检查序列元素,你会发现它是一个特殊类型:
x = data['DataSecurityContainer']['items'][0]
print(x, type(x))
输出结果:
61953922709457582312898796139505834842512090556466629792920972610962764374133 <class 'ruamel.yaml.scalarint.HexInt'>
要创建所需的输出,你需要创建一个 HexInt
实例,可以从从输入文件中读取的字符串构造的整数创建:
import sys
from pathlib import Path
import ruamel.yaml
value = '0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075'
data = dict(DataSecurityContainer=dict(items=[ ruamel.yaml.scalarint.HexInt(int(value, 0)) ]))
path = Path('temp.yaml')
yaml = ruamel.yaml.YAML()
yaml.dump(data, path)
sys.stdout.write(path.read_text())
输出结果:
DataSecurityContainer:
items:
- 0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075
从文件中读取字符串 value
并通过加载包含YAML文档的文件创建 data
是非常简单的,唯一的 '魔法' 在于将 value
转换为 HexInt()
(并且放弃了长时间过时的PyYAML)。
英文:
I recommend you upgrade to my ruamel.yaml
. It supports YAML 1.2, can preserve comments, tags, etc, including the formatting
of an integer:
import sys
import ruamel.yaml
yaml_str = """\
DataSecurityContainer:
items:
- 0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075 # scalar loaded as integer subclass
"""
yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)
which gives:
DataSecurityContainer:
items:
- 0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075 # scalar loaded as integer subclass
if you inspect that sequence element, you see that it is a special type:
x = data['DataSecurityContainer']['items'][0]
print(x, type(x))
printing:
61953922709457582312898796139505834842512090556466629792920972610962764374133 <class 'ruamel.yaml.scalarint.HexInt'>
To create the required output, you create a HexInt
instance, which you can do from the integer constructed from the string
you would read from the input file:
import sys
from pathlib import Path
import ruamel.yaml
value = '0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075'
data = dict(DataSecurityContainer=dict(items=[ ruamel.yaml.scalarint.HexInt(int(value, 0)) ]))
path = Path('temp.yaml')
yaml = ruamel.yaml.YAML()
yaml.dump(data, path)
sys.stdout.write(path.read_text())
which gives:
DataSecurityContainer:
items:
- 0x88f8ad77bb388f63674991a8692618a459bec731d15e6c8cf3755050af98a075
And it is trivial to read the string value
from a file and create data
by loading a file containing a YAML document,
the only 'magic' is in converting value to a HexInt()
(and dropping the long outdated PyYAML).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论