问题描述
我正在尝试在 cpython 中创建一个自定义类型,该类型继承自 Python 中已定义的类型对象。到目前为止,我的方法是使用 public class RomanNumberUtils {
static String romanNumeral;
static int decimalNum;
public static void main(String args[]) {
RomanNumberUtils roman = new RomanNumberUtils();
roman .convertRomanToDecimal();
roman .printRoman(romanNumeral);
}
public void convertRomanToDecimal () {
Scanner scan = new Scanner(system.in);
System.out.print("Enter a Roman number: ");
romanNumeral = scan.nextLine();
romanNumeral = romanNumeral.toupperCase();
int l= romanNumeral.length();
int num=0;
int prevIoUsnum = 0;
for (int i=l-1;i>=0;i--)
{
char x = romanNumeral.charat(i);
x = Character.toupperCase(x);
switch(x)
{
case 'I':
prevIoUsnum = num;
num = 1;
break;
case 'V':
prevIoUsnum = num;
num = 5;
break;
case 'X':
prevIoUsnum = num;
num = 10;
break;
case 'L':
prevIoUsnum = num;
num = 50;
break;
case 'C':
prevIoUsnum = num;
num = 100;
break;
case 'D':
prevIoUsnum = num;
num = 500;
break;
case 'M':
prevIoUsnum = num;
num = 1000;
break;
}
if (num<prevIoUsnum)
{decimalNum= decimalNum-num;}
else
decimalNum= decimalNum+num;
}
}
public static void printRoman (String romanNumeral){
System.out.println ("The equivalent of the Roman numeral "+romanNumeral+" is "+decimalNum);
}
}
,然后访问 PyImport_ImportModule
并将其设置为我的 PyTypeObject
中的 tp_base
属性。
导入:
PyTypeObject
继承:
PyTypeObject typeObj = {...} // PrevIoUsly defined PyTypeObject for a fallback
int init() {
PyObject* obj = PyImport_ImportModule("<absolute_path_to_python_module>");
if (obj && PyObject_Hasstring(obj,"<python_type_object>")) {
PyTypeObject* type_ptr = (PyTypeObject*) PyObject_GetAttrString(obj,"<python_type_object>");
typeObj = *type_ptr;
}
if (PyType_Ready(&typeObj) < 0) return -1;
... // Other initialization stuff
}
自定义类型能够继承函数,但在 PyTypeObject CustomType = {
... // Initialization stuff
.tp_base = &typeObj;
};
上失败。当我尝试访问自定义类型的 isinstance(CustomType(),TypeObj)
属性时,它会引发分段错误。
解决方法
类型由身份标识,而不是值。当您尝试执行 typeObj = *type_ptr;
时,即使它“有效”,typeObj
的内存地址与 *type_ptr
不同,并且永远不会被视为相同的类型。您需要保留身份。
将您的代码更改为:
PyTypeObject fallback_type_obj = {...} // Previously defined PyTypeObject for a fallback
PyTypeObject *type_ptr = NULL;
int init() {
PyObject* obj = PyImport_ImportModule("<absolute_path_to_python_module>");
if (obj && PyObject_HasString(obj,"<python_type_object>")) {
type_ptr = (PyTypeObject*) PyObject_GetAttrString(obj,"<python_type_object>");
}
if (type_ptr == NULL) {
if (PyType_Ready(&fallback_type_obj) < 0) return -1;
type_ptr = &fallback_type_obj;
}
... // Other initialization stuff
}
然后创建一个使用 type_ptr
作为基础的堆类型(静态/全局类型不起作用,因为 type_ptr
没有被静态初始化为任何有用的东西)。