无需Numpy,如何通过Python C API创建数组?是否参考arraymodule.c?
array.array Objects via the Python C API (No NumPy Needed) Absolutely you can create and manipulate Python array.array objects directly using the Python C API—perfect for when NumPy isn't an option. Let's walk through exactly how to do this, plus confirm your reference file question.
Is arraymodule.c the right reference?
Yes! arraymodule.c is the official C source code for Python's built-in array module. It contains all the implementation details, type definitions, and internal logic for array.array objects. If you want to dig into how the module works under the hood (or even use some of its internal helper functions, though public API is preferred for compatibility), this is the exact file to reference.
Step-by-Step Implementation
Here's a complete, practical example of creating a Python array.array in C, populating it with data, and verifying the result:
1. Basic Setup & Initialization
First, you need to initialize the Python interpreter (if it's not already running in your embedding/extension context) and import the array module.
2. Create the Array Instance
Use the Python C API to fetch the array.array class, then call its constructor with a type code (defining the array's element type) and optional initial data.
3. Manipulate the Array
Use standard array methods like append() via the C API to add elements, or access elements directly if needed.
Full Example Code
#include <Python.h> #include <stdio.h> int main() { // Initialize the Python interpreter if (!Py_Initialize()) { fprintf(stderr, "Failed to initialize Python interpreter\n"); return 1; } // Import the built-in `array` module PyObject* array_module = PyImport_ImportModule("array"); if (!array_module) { PyErr_Print(); Py_Finalize(); return 1; } // Get the `array.array` class object PyObject* array_class = PyObject_GetAttrString(array_module, "array"); if (!array_class) { PyErr_Print(); Py_DECREF(array_module); Py_Finalize(); return 1; } // 1. Create an empty array of signed 32-bit integers (type code 'i') PyObject* int_array = PyObject_CallFunction(array_class, "s", "i"); if (!int_array) { PyErr_Print(); Py_DECREF(array_class); Py_DECREF(array_module); Py_Finalize(); return 1; } // Append elements to the array for (int i = 0; i < 5; i++) { if (!PyObject_CallMethod(int_array, "append", "i", i * 10)) { PyErr_Print(); Py_DECREF(int_array); Py_DECREF(array_class); Py_DECREF(array_module); Py_Finalize(); return 1; } } // 2. Alternative: Create an array initialized from a C array int c_data[] = {100, 200, 300}; size_t data_len = sizeof(c_data) / sizeof(c_data[0]); // Convert C array to a Python tuple (usable as initial data) PyObject* py_initial_data = PyTuple_New(data_len); for (size_t i = 0; i < data_len; i++) { PyTuple_SetItem(py_initial_data, i, PyLong_FromLong(c_data[i])); } PyObject* prefilled_array = PyObject_CallFunction(array_class, "sO", "i", py_initial_data); if (prefilled_array) { printf("Prefilled array: "); PyObject_Print(prefilled_array, stdout, 0); printf("\n"); } else { PyErr_Print(); } // Clean up the initial data tuple Py_DECREF(py_initial_data); // Print the dynamically populated array printf("Dynamically populated array: "); PyObject_Print(int_array, stdout, 0); printf("\n"); // Clean up all Python object references to avoid leaks Py_DECREF(int_array); Py_DECREF(prefilled_array); Py_DECREF(array_class); Py_DECREF(array_module); // Shut down the Python interpreter Py_Finalize(); return 0; }
Key Notes:
- Type Codes: The first argument to
array.arrayis a type code string (e.g.,'i'for int32,'f'for float32,'b'for int8). See Python'sarraymodule docs for the full list of valid codes. - Reference Counting: Always manage references with
Py_DECREF()for objects you own (most C API functions return new references). This prevents memory leaks. - Error Handling: Check for
NULLreturns from API calls and usePyErr_Print()to debug Python-level errors.
Compiling the Example
To compile this code (assuming you have Python development headers installed), use a command like:
gcc -o array_example array_example.c $(python3-config --cflags --ldflags)
Run the executable, and you'll see the two arrays printed to the console.
内容的提问来源于stack exchange,提问作者shuttle87

