Golang替代Python的pprint.pformat方法
Golang替代Python的pprint.pformat方法 我正在将Python CLI用Go语言重写,以便利用我想使用的网络效应。我面临的一个挑战是,似乎找不到Python的pprint.pformat的替代品。
我知道有go-spew,但这个项目似乎已经停止维护了,因为它甚至没有go.mod文件。
我也知道fmt.Printf,但用它来重建相同的用户体验将比我预期的要费事得多。
更多关于Golang替代Python的pprint.pformat方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
感谢您的建议!我认为这基本满足了我的需求,因此本主题可以视为已解决。
我知道 JSON 编码器,但我认为它与美化打印是不同的用例,因为编码器会相当大地改变输出。而使用美化打印,对象的内部表示得以保留。
更多关于Golang替代Python的pprint.pformat方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
如果你想输出格式美观的 JSON,可以随时使用 MarshalIndent:
json package - encoding/json - Go Packages
Package json implements encoding and decoding of JSON as defined in RFC 7159.
详情请参阅此 StackOverflow 回答。如果你希望拥有更多控制权,就必须使用反射(类似于你链接的那个包的做法)。下面这个包看起来也很有趣:
pretty package - github.com/kr/pretty - Go Packages
Package pretty provides pretty-printing for Go values.
在Go语言中,虽然没有直接等同于Python pprint.pformat 的内置方法,但可以通过标准库和第三方库实现类似的功能。以下是几种解决方案:
1. 使用标准库 encoding/json
对于JSON格式的可读输出,可以使用json.MarshalIndent:
package main
import (
"encoding/json"
"fmt"
)
func main() {
data := map[string]interface{}{
"name": "John",
"age": 30,
"address": map[string]interface{}{
"street": "123 Main St",
"city": "Boston",
},
"hobbies": []string{"reading", "gaming", "coding"},
}
// 类似pprint.pformat的格式化输出
formatted, _ := json.MarshalIndent(data, "", " ")
fmt.Println(string(formatted))
}
2. 使用 fmt.Printf 的 %#v 格式符
对于调试目的,%#v 可以输出Go语法表示的值:
package main
import "fmt"
type Person struct {
Name string
Age int
Address struct {
Street string
City string
}
}
func main() {
p := Person{
Name: "Alice",
Age: 25,
}
p.Address.Street = "456 Oak Ave"
p.Address.City = "Seattle"
// 输出Go语法表示
fmt.Printf("%#v\n", p)
}
3. 使用 go-spew(虽然无go.mod但功能完整)
尽管没有go.mod,但go-spew仍然可以工作:
package main
import (
"github.com/davecgh/go-spew/spew"
)
func main() {
complexData := []map[string]interface{}{
{
"id": 1,
"data": []int{1, 2, 3, 4, 5},
},
{
"id": 2,
"data": []string{"a", "b", "c"},
},
}
// 使用spew.Dump(类似pprint)
spew.Dump(complexData)
// 获取格式化字符串(类似pformat)
formatted := spew.Sdump(complexData)
fmt.Println(formatted)
}
4. 使用 k8s.io/klog/v2 的 PrettyPrint
如果你不介意引入k8s的库:
package main
import (
"fmt"
"k8s.io/klog/v2"
)
func main() {
data := struct {
Users []string
Count int
}{
Users: []string{"user1", "user2", "user3"},
Count: 3,
}
// 使用klog的格式化
formatted := klog.PrettyPrint(data)
fmt.Println(formatted)
}
5. 自定义格式化函数
创建自己的pformat函数:
package main
import (
"encoding/json"
"fmt"
"reflect"
"strings"
)
func pformat(v interface{}, indent string) string {
return formatValue(reflect.ValueOf(v), indent, 0)
}
func formatValue(v reflect.Value, indent string, depth int) string {
switch v.Kind() {
case reflect.Struct:
var parts []string
parts = append(parts, "{\n")
for i := 0; i < v.NumField(); i++ {
fieldName := v.Type().Field(i).Name
fieldValue := formatValue(v.Field(i), indent, depth+1)
parts = append(parts,
strings.Repeat(indent, depth+1)+
fieldName+": "+fieldValue+",\n")
}
parts = append(parts, strings.Repeat(indent, depth)+"}")
return strings.Join(parts, "")
case reflect.Slice, reflect.Array:
var parts []string
parts = append(parts, "[\n")
for i := 0; i < v.Len(); i++ {
elem := formatValue(v.Index(i), indent, depth+1)
parts = append(parts,
strings.Repeat(indent, depth+1)+elem+",\n")
}
parts = append(parts, strings.Repeat(indent, depth)+"]")
return strings.Join(parts, "")
case reflect.Map:
var parts []string
parts = append(parts, "{\n")
iter := v.MapRange()
for iter.Next() {
key := formatValue(iter.Key(), indent, depth+1)
value := formatValue(iter.Value(), indent, depth+1)
parts = append(parts,
strings.Repeat(indent, depth+1)+
key+": "+value+",\n")
}
parts = append(parts, strings.Repeat(indent, depth)+"}")
return strings.Join(parts, "")
default:
return fmt.Sprintf("%v", v.Interface())
}
}
func main() {
data := map[string]interface{}{
"name": "test",
"values": []int{1, 2, 3},
}
fmt.Println(pformat(data, " "))
}
对于大多数用例,encoding/json 的 MarshalIndent 提供了最接近 pprint.pformat 的功能,特别是处理嵌套数据结构时。如果需要在CLI中保持与Python版本相似的用户体验,建议使用JSON格式化输出或实现自定义的格式化函数。

