Почему я вижу ошибку “не удается импортировать имя descriptor_pb2” при использовании буферов протокола Google?
-
11-09-2019 - |
Вопрос
При использовании сгенерированного кода Python из наших классов protobuf мы получаем эту ошибку:
cannot import name descriptor_pb2
Эквивалентный сгенерированный на C ++ код работает просто отлично, так что, похоже, с нашими реальными прототипными определениями проблем нет.
Эта ошибка возникает, когда я пытаюсь импортировать наш класс, вот так:
import sys
sys.path.append('..\path\to\generated')
sys.path.append('..\contrib\protobuf\python')
from foobar_pb2 import FooBar
Правильно ли добавлять системные пути?
Я проверил в protobuf\python\google\protobuf
каталог для descriptor_pb2.py
но только нашел descriptor.py
- мы используем последнюю версию, поэтому я предполагаю, что у нас нет пропавших файлов.
Кто-нибудь знает, в чем заключается решение?
Решение
Я считаю, что вам нужно создать descriptor_pb2.py
с protoc
сам:
protoc descriptor.proto --python_out=gen/
gen/
— это папка с сгенерированными классами Python.
После этого следующее работает нормально:
sys.path.append('../gen')
from descriptor_pb2 import FileDescriptorSet
../gen/descriptor_pb2.py
должно существовать.
Другие советы
В моем случае descriptor_pb2 не был найден из-за того, что protobuf был установлен неправильно.В подкаталоге python protobuf обязательно запустите
python setup.py build
python setup.py test
python setup.py install (as root)
Обязательно установите библиотеку времени выполнения protobuf, как указано в файле readme.Вы не можете просто использовать исходный код непосредственно из пакета, поскольку descriptor_pb2.py должен быть сгенерирован protoc (компилятором protobuf) как часть процесса установки.
Я использую Python 2.7 в Windows 10.
В моем случае я скачал protoc-3.0.0-beta-2-win32 с сайта https://github.com/google/protobuf/releases и скопировал двоичный файл протокола в папку src.
после этого я выполнил команду сборка python setup.py и был создан descriptor_pb2.
python setup.py сборка
Этот шаг является обязательным, поскольку он сгенерировал некоторые исходные файлы.
Генерирующий google/protobuf/descriptor_pb2.py...Генерирую google/protobuf/compiler/plugin_pb2.py...Генерирую google/protobuf/unittest_pb2.py...Генерирую google/protobuf/unittest_custom_options_pb2.py...Генерирую google/protobuf/unittest_import_pb2.py...Генерирую google/protobuf/unittest_import_public_pb2.py...Генерирую google/protobuf/unittest_mset_pb2.py...Генерирую google/protobuf/unittest_no_generic_services_pb2.py...Генерирую google/protobuf/internal/descriptor_pool_test1_pb2.py...Генерирую google/protobuf/internal/descriptor_pool_test2_pb2.py...Генерирую google/protobuf/internal/test_bad_identifiers_pb2.py...Генерирую google/protobuf/internal/missing_enum_values_pb2.py...Генерирую google/protobuf/internal/more_extensions_pb2.py...Генерирую google/protobuf/internal/more_extensions_dynamic_pb2.py...Генерирую google/protobuf/internal/more_messages_pb2.py...Генерирую google/protobuf/internal/factory_test1_pb2.py...Генерирую google/protobuf/internal/factory_test2_pb2.py...Генерирую google/protobuf/pyext/python_pb2.py...бла...
Именно 'descriptor_pb2.py'