gpt4 book ai didi

python - 如何同时使用 Go 和 Python 处理 YAML 中的十六进制值?

转载 作者:IT王子 更新时间:2023-10-29 02:00:59 26 4
gpt4 key购买 nike

我有这个简单的以下程序:

package main

import (
"fmt"

yaml "gopkg.in/yaml.v2"
)

type Test struct {
SomeStringWithQuotes string `yaml:"someStringWithQuotes"`
SomeString string `yaml:"someString"`
SomeHexValue string `yaml:"someHexValue"`
}

func main() {
t := Test{
SomeStringWithQuotes: "\"Hello World\"",
SomeString: "Hello World",
SomeHexValue: "0xDef9C64256DeE61ebf5B212238df11C7E532e3B7",
}
yamlBytes, _ := yaml.Marshal(t)
fmt.Print(string(yamlBytes))
}

这将打印以下内容,并明显地表明 Go 决定何时引用字符串:

someStringWithQuotes: '"Hello World"'
someString: Hello World
someHexValue: 0xDef9C64256DeE61ebf5B212238df11C7E532e3B7

但是,当我尝试使用以下 Python 脚本读取此 YAML 时:

import yaml

yaml_str = """
someStringWithQuotes: '"Hello World"'
someString: Hello World
someHexValue: 0xDef9C64256DeE61ebf5B212238df11C7E532e3B7
"""

print(yaml.load(yaml_str))

它将十六进制值解析为整数。如果我现在使用此代码序列化回 YAML:

import yaml
import sys

yaml_str = """
someStringWithQuotes: '"Hello World"'
someString: Hello World
someHexValue: 0xDef9C64256DeE61ebf5B212238df11C7E532e3B7
"""

print(yaml.dump(yaml.load(yaml_str)))

我得到:

someHexValue: 1272966107484048169783147972546098614451903325111
someString: Hello World
someStringWithQuotes: '"Hello World"'

如何才能最好地确保保留十六进制格式?不幸的是,我个人对 Go 端的代码没有任何影响(但对于尝试做类似事情的其他人来说,Go 端的解决方案仍然是受欢迎的)。

最佳答案

您可以在 Python 中加载和转储该输出,同时使用 ruamel.yaml 保留十六进制值(免责声明:我是该 Python 包的作者):

import sys
import ruamel.yaml

yaml_str = """\
someHexValue: 0xDef9C64256DeE61ebf5B212238df11C7E532e3B7
someString: Hello World
someStringWithQuotes: '"Hello World"'
"""

yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)

给出:

someHexValue: 0xDEF9C64256DEE61EBF5B212238DF11C7E532E3B7
someString: Hello World
someStringWithQuotes: '"Hello World"'

go的实际输出是不正确的,如果你用Python输出字符串"0xDef9C64256DeE61ebf5B212238df11C7E532e3B7",那么你会看到它输出那个带引号的字符串(我在这里使用 ruamel.yaml,但这对 PyYAML 是一样的):

import sys
import ruamel.yaml

data = dict(someHexValue="0xDef9C64256DeE61ebf5B212238df11C7E532e3B7")

yaml = ruamel.yaml.YAML()
yaml.dump(data, sys.stdout)

给出:

someHexValue: '0xDef9C64256DeE61ebf5B212238df11C7E532e3B7'

这个字符串需要引用,由表示字符串“plain”(即不带引号)然后尝试解析它确保返回原始类型(字符串)。这不是情况下,因为它被发现是一个整数和倾销过程决定报价是必要的。 (如果你看过在加载和转储代码中,想知道为什么使用解析器双方:这就是转储程序需要访问 resolver.py 的原因好吧)。

这对于像 "True" 和 "2019-02-08' 这样的字符串也是一样的,它们也被引用(按顺序不要将它们与 bool 值或日期“混淆”。

这是一个相当昂贵的计算过程,当然还有其他方法确定是否需要报价。

在go中也是这样,只是resolve.go中的相关代码有错误:

        intv, err := strconv.ParseInt(plain, 0, 64)
if err == nil {
if intv == int64(int(intv)) {
return yaml_INT_TAG, int(intv)
} else {
return yaml_INT_TAG, intv
}
}

来自 ParseInt 的文档:

If base == 0, the base is implied by the string's prefix: base 16 for "0x", base 8 for "0", and base 10 otherwise.

问题当然是 YAML 和Python 关于整数的大小。但是在围棋中限制为 64位。所以在上面的 ParseInt 返回一个错误并且去认为字符串不需要引号。 (我将此报告为 bug在 go-yaml 中图书馆)。

去吧Marshall函数似乎没有标志来强制引用在 ruamel.yaml`` 中设置 yaml.default_style = '"'`。








关于python - 如何同时使用 Go 和 Python 处理 YAML 中的十六进制值?,我们在Stack Overflow上找到一个类似的问题:

https://stackoverflow.com/questions/54584832/




26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com