TL, DR; Как можно записать десятичный экземпляр Python. Десятичный в поле "Буфер протокола" double
?
Detail; В буферах протокола Python поле скалярного сообщения *1009* может быть double
.
При наличии экземпляра Python десятичный. десятичный класс:
# Intentionally high-precision number.
d = Decimal(3.14159265358979323846264)
... и буфер протокола определение:
message Test {
double value = 1;
}
Я хотел бы попытку для заполнения Test.value
:
d = Decimal(3.14159265358979323846264)
try:
my_proto_pb2.Test(value=d)
except ValueError:
# Could not store in a `double`.
Как и ожидалось, это поднимает TypeError
.Обратите внимание, что я except
использую ValueError
, потому что это то, что вызывает модуль Python ProtoBuffer type_checkers.py .Я хочу ValueError
.Я не хочу TypeError
:)
TypeError:
Decimal('3.14159265358979323846264')
has type <class 'decimal.Decimal'>,
but expected one of: ((<class 'numbers.Real'>,),) for field Test.value
Я ожидал этого, однако преобразование Decimal
в float
приведет к потере точности до протокол заполняется:
d = Decimal(3.14159265358979323846264)
try:
my_proto_pb2.Test(value=float(d))
except ValueError:
# Could not store in a `double`.
Нет TypeError
, но Test.value
содержит 3.141592653589793
Реализация протокольных буферов в Python использует TypeChecker, чтобы определить, является ли тип изначения совместимы.См. google / protobuf / internal / type_checkers.py .Однако есть только следующие контролеры:
- IntValueChecker
- EnumValueChecker
- UnicodeValueChecker
- Int32ValueChecker
- Uint32ValueChecker
- Int64ValueChecker
- Uint64ValueChecker
Следовательно, следующий код работает для очень больших целых чисел , поскольку Int64ValueChecker
повышает ValueError
:
message AnotherTest {
int64 value = 1;
}
... и соответствующий Python:
n = 18446744073709551616
try:
value = my_proto.AnotherTest(value=int(n))
except ValueError:
# Could not store in a `int64`.