Python C / API:如何创建普通类

时间:2016-10-10 12:51:54

标签: python class python-c-api

使用Python C / API,如何使用普通的Python类创建机制创建普通的Python类(即:不是扩展类型)?

换句话说,什么是Python C / API等价物(在某种意义上它在所有情况下完全相同)的语句

class X(bases):
    ...some methods/attributes here...

2 个答案:

答案 0 :(得分:4)

在Python中,您可以通过调用// Add your native dependencies here: // Uncomment to add recyclerview-v7 dependency //dependencies { // compile 'com.android.support:recyclerview-v7:+' //} import groovy.json.JsonSlurper //used to parse package.json def tnsBuildMultipleApks=true; String content = new File("$projectDir/../../app/package.json").getText("UTF-8") def jsonSlurper = new JsonSlurper() def appPackageJson = jsonSlurper.parseText(content) android { defaultConfig { generatedDensities = [] applicationId = appPackageJson.nativescript.id versionCode = appPackageJson.version_code ?: 1 } aaptOptions { additionalParameters "--no-version-vectors" } if (Boolean.valueOf(tnsBuildMultipleApks)) { splits { abi { enable true reset() include 'x86', 'armeabi-v7a', 'arm64-v8a' universalApk true } } } } // map for the version code that gives each ABI a value ext.versionCodes = [ 'x86':1, 'armeabi-v7a':2, 'arm64-v8a':3 ] // For each APK output variant, override versionCode with a combination of // ABI APK value * 100 + android.defaultConfig.versionCode // getAbiFilter() not working for me so I extracted it from getFullname() if (Boolean.valueOf(tnsBuildMultipleApks)) { android.applicationVariants.all { variant -> println(appPackageJson) println(android.defaultConfig.versionCode) println(android.defaultConfig.applicationId) def name def flavorNamesConcat = "" variant.productFlavors.each() { flavor -> flavorNamesConcat += flavor.name } flavorNamesConcat = flavorNamesConcat.toLowerCase() println(flavorNamesConcat) variant.outputs.each { output -> if (output.outputFile != null && output.outputFile.name.endsWith('.apk')) { //You may look for this path in your console to see what the values are println("******************************************************") println(output); println(output.getVariantOutputData().getFullName()) def abiName = output.getVariantOutputData().getFullName().toLowerCase().replace(flavorNamesConcat, "").replace(project.ext.selectedBuildType, "") println(abiName) def file = output.outputFile output.versionCodeOverride = project.ext.versionCodes.get(abiName, 0) * 100 + android.defaultConfig.versionCode def apkDirectory = output.packageApplication.outputFile.parentFile def apkNamePrefix = output.outputFile.name.replace(".apk", "-" + abiName) if (output.zipAlign) { name = apkNamePrefix + ".apk" output.outputFile = new File(apkDirectory, name); } name = apkNamePrefix + "-unaligned.apk" output.packageApplication.outputFile = new File(apkDirectory, name); } } } } 内置函数以编程方式创建类。例如,请参阅this answer

这需要三个参数:名称,基础元组和字典。

您可以将C api中的Python type设为PyType_Type。然后,您只需使用one of the standard methods for calling PyObject* callables调用它:

type

(请注意,您必须执行// make a tuple of your bases PyObject* bases = PyTuple_Pack(0); // assume no bases // make a dictionary of member functions, etc PyObject* dict = PyDict_New(); // empty for the sake of example PyObject* my_new_class = PyObject_CallFunction(&PyType_Type,"sOO", "X", // class name bases, dict); // check if null // decref bases and dict Py_CLEAR(bases); Py_CLEAR(dict); - 文档暗示它是&PyType_Type,但事实并非如此!)

答案 1 :(得分:1)

我不确定“普通的Python类创建机制”是什么意思,但是......

有一个专门针对此的文档页面:https://docs.python.org/3/extending/newtypes.html - 它在扩展模块中创建一个新类型,相当于在Python代码中创建一个新的class

这里提出的最小例子是:

#include <Python.h>

typedef struct {
    PyObject_HEAD
    /* Type-specific fields go here. */
} noddy_NoddyObject;

static PyTypeObject noddy_NoddyType = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "noddy.Noddy",             /* tp_name */
    sizeof(noddy_NoddyObject), /* tp_basicsize */
    0,                         /* tp_itemsize */
    0,                         /* tp_dealloc */
    0,                         /* tp_print */
    0,                         /* tp_getattr */
    0,                         /* tp_setattr */
    0,                         /* tp_reserved */
    0,                         /* tp_repr */
    0,                         /* tp_as_number */
    0,                         /* tp_as_sequence */
    0,                         /* tp_as_mapping */
    0,                         /* tp_hash  */
    0,                         /* tp_call */
    0,                         /* tp_str */
    0,                         /* tp_getattro */
    0,                         /* tp_setattro */
    0,                         /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT,        /* tp_flags */
    "Noddy objects",           /* tp_doc */
};

static PyModuleDef noddymodule = {
    PyModuleDef_HEAD_INIT,
    "noddy",
    "Example module that creates an extension type.",
    -1,
    NULL, NULL, NULL, NULL, NULL
};

PyMODINIT_FUNC
PyInit_noddy(void)
{
    PyObject* m;

    noddy_NoddyType.tp_new = PyType_GenericNew;
    if (PyType_Ready(&noddy_NoddyType) < 0)
        return NULL;

    m = PyModule_Create(&noddymodule);
    if (m == NULL)
        return NULL;

    Py_INCREF(&noddy_NoddyType);
    PyModule_AddObject(m, "Noddy", (PyObject *)&noddy_NoddyType);
    return m;
}