我有兴趣在c的扩展中创建decimal.Decimal
对象。我在文档
中找不到关于此的任何文档。有相关的文档吗?有其他例子吗?
我已经在Python git存储库中找到了实现该对象的源代码,因此我确信我可以做一些试验和错误,并通过处理头文件导入来混淆,但首选文档(如果存在的话)。
在Python 3.10中,将会有一个C API用于此。您需要提供自己的libmpdec和mpdecimal.h
头文件,并使用import_decimal()
初始化十进制API。(请注意,c级import_decimal()
调用与python级语句import decimal
完全不同,并且与之无关。)
设置完成后,可以使用
分配未初始化的Decimal对象。PyObject *dec = PyDec_Alloc();
然后用
获取一个指向内部mpd_t
的指针mpd_t *dec_internal = PyDec_Get(dec);
并使用libmpdec函数初始化mpd_t
。(注意,十进制对象在逻辑上是不可变的,所以除了用PyDec_Alloc
分配的对象之外,您应该避免改变任何十进制对象。)
要使用现有Decimal对象的mpd_t
,可以执行
const mpd_t *dec_internal = PyDec_GetConst(some_existing_decimal);
,然后使用非变化的libmpdec函数。
对于3.10之前的代码,没有Decimal C API。你只需要使用PyImport_ImportModule
、PyObject_GetAttrString
和PyObject_Call
这样的函数来完成c级的import decimal; d = Decimal(whatever)
。
您的问题是关于decimal.Decimal
类,而链接的代码指向使用库libmpdec
的优化模块_decimal
。
下面的代码片段将在Python 3.9中适用于所有三种情况(decimal/_decimal/_pydecimal)。
PyObject *module = PyImport_ImportModule((char *) "decimal");
PyObject *clazz = PyObject_GetAttrString(module, (char *) "Decimal");
PyObject *value = PyUnicode_FromString("123.45");
PyObject *object = PyObject_CallOneArg(clazz, value);
PyObject *str = PyObject_Str(object);
// C++
std::cout << "dec: " << PyUnicode_AsUTF8(str) << std::endl;
// C
// printf("dec: %sn", PyUnicode_AsUTF8(str));
输出:
dec: 123.45
关于Python 3.3中_decimal
实现的一些背景信息可以在https://bugs.python.org/issue7652