虽然我已经遵循了优秀的协议缓冲区文档和C ++和Python教程,但我无法实现我的目标: - 从C ++进程序列化数据。 - 从同一个进程将其插入LevelDB。 - 从Python进程中提取序列化数据 - 从同一个Python进程中去除它 - 在Python中使用那些deseralized数据
我可以使用C ++中的协议缓冲区序列化我的数据(使用std :: string容器)。我可以将它插入LevelDB。但是,当我在levelDB->获取我的序列化数据时,尽管Python似乎将它识别为String,并向我显示它们的原始内容,每当我将其反序列化为Python String时,它都是空的!
以下是我在C ++中序列化和插入数据的方法:
int main(int arg, char** argv)
{
GOOGLE_PROTOBUF_VERIFY_VERSION;
leveldb::DB* db;
leveldb::Options options;
leveldb::Status status;
tutorial::AddressBook address_book;
tutorial::Person* person1;
tutorial::Person* person2;
options.create_if_missing = true;
status = leveldb::DB::Open(options, "test_db", &db);
assert(status.ok());
person1 = address_book.add_person();
person1->set_id(1);
person1->set_name("ME");
person1->set_email("me@me.com");
person2 = address_book.add_person();
person2->set_id(2);
person2->set_name("SHE");
person2->set_email("she@she.com");
std::string test;
if (!address_book.SerializeToString(&test))
{
std::cerr << "Failed to write address book" << std::endl;
return -1;
}
if (status.ok()) status = db->Put(leveldb::WriteOptions(), "Test", test);
以下是我尝试在Python中反序列化的方法:
address_book = addressbook_pb2.AddressBook()
db = leveldb.LevelDB('test_db')
ab = address_book.ParseFromString(db.Get("Test"))
ad var type是NoneType
编辑:
在db.Get()之前,ab.ByteSize()在ParseFromString()之后返回0,76,我认为它是Type问题然后......
+
ab.ListFields()返回包含字段的unexploitable
列表:成功地couting两个人实例,但无法让我访问它。
任何线索,任何我不理解的想法,我在这里做错了什么?
非常感谢!
答案 0 :(得分:1)
好的,所以这是我的坏事。
我回到了Protocol Buffers Python文档,事实是,即使我正在检索的AdressBook对象没有显示任何描述,它仍然可以迭代甚至有一个。 str < / strong>()方法。
所以,如果有人再次遇到这个问题,就像我一样尝试使用iPython探索你的ProtocolBuffers对象,你会发现你的每个proto元素都是你对象的字段。 用我的例子:
ab = adress_book.ParseFromString(db.Get('Test'))
ab.__str__() # Shows a readable version of my object
for person in adress_book.person: # I'm even able to iterate over any of my ab fields values
print person.id
print person.name
答案 1 :(得分:0)
尝试使用'
代替"
:
ab = address_book.ParseFromString(db->Get('Test'))