初衷
我们产品有很多状态信息都持久化到文件中,从而数据库意外中断后重启还能知道之前的状态信息。文件中数据是按c struct直接灌进去的,所以我想写个通用类用来漂亮的显示文件内容。
大概如此这般展示:
STAT_FILEHD size: 0x258
+0 version=64
+4 filetype=b'\x07'
+5 cfgflags=b'\x00'
+6 num=2
+0 name=b'g0'
+128 acct=b'TESTACCT'
求助人工智能
先用免费的ChatGPT3.5把需求描述个大概
你能否编写一个继承自ctypes.Structure的Python类,命名为PrettyPrintableStruct,以便我可以写一个新类, 比如叫Person,它继承自PrettyPrintableStruct从而轻松打印?以下是要求:1. 一个字段打印一行,前缀为十六进制的偏移量,后缀为值,字段名称位于中间。
2. 如果字段是ctypes.Structure的子类,则再次执行第1步,缩进一个制表符。
import ctypes
class PrettyPrintableStruct(ctypes.Structure):
def print_fields(self, prefix="", indent=""):
for field_name, field_type in self._fields_:
field_value = getattr(self, field_name)
print(f"{prefix}Offset: 0x{getattr(self, field_name).offset:02X}, Field: {field_name}, Value: {field_value}")
if issubclass(field_type, ctypes.Structure):
field_value.print_fields(prefix=prefix, indent=indent + "\t")
# 示例用法
class Person(PrettyPrintableStruct):
_fields_ = [("name", ctypes.c_char_p),
("age", ctypes.c_int),
("address", ctypes.c_char_p)]
# 创建一个Person实例
p = Person()
p.name = "Alice"
p.age = 30
p.address = "123 Main St"
# 打印Person实例的字段
p.print_fields()
修修补补
这里面有些错误,但雏形有了,我只需要简单改改
import ctypes
from rich.columns import Console
console = Console()
print=console.print #color the print
class ChatGPTPrettyPrintableStruct(ctypes.Structure):
_fields_explain_ = {}
# from chatGPT
def __str__(self, indent=4):
result = []
for field_name, field_type in self._fields_:
value = getattr(self, field_name)
offset = getattr(type(self), field_name).offset
serializer = self._fields_explain_.get(field_name)
if serializer:
value = serializer(value)
elif issubclass(field_type, ctypes.Structure):
value = "\n" + value.__str__(indent + 4)
result.append(f"{' ' * indent}+{offset} {field_name}={value}")
return "\n".join(result)
class Feet(ChatGPTPrettyPrintableStruct):
_fields_ = [("leftLen", ctypes.c_int),
("rightLen", ctypes.c_int)]
class Person(ChatGPTPrettyPrintableStruct):
_fields_ = [("name", ctypes.c_char*5),
("age", ctypes.c_int),
("feet", Feet),
("address", ctypes.c_char*20)]
# 创建一个Person实例
p = Person()
p.name = "Alice".encode('utf-8')
p.age = 30
p.feet = Feet()
p.feet.leftLen = 5
p.feet.rightLen = 6
p.address = "123 Main St".encode('utf-8')
print(p)
还通过引入rich模块加了点color,效果如下:
我现在已经离不开ChatGPT当辅助了。 ChatGPT4刚开始免费时我试过确实比3.5厉害,可惜现在用不了了。