使用Python C / API,如何使用普通的Python类创建机制创建普通的Python类(即:不是扩展类型)?
换句话说,什么是Python C / API等价物(在某种意义上它在所有情况下完全相同)的语句
class X(bases):
...some methods/attributes here...
答案 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;
}