MicroPython 是一种适用于微控制器和其他受限环境的 Python 编程语言的实现。它旨在提供与 Python 3 语言的紧密兼容,同时考虑到内存和计算资源的限制。MicroPython 库是这门语言的核心组成部分,提供了一系列的模块和函数,使得开发者能够在硬件上执行各种任务。
下面将通过系列文章,逐一解读microPython,以便让读者了解掌握microPython的整个核心逻辑.,以便读者可以透过这个Python的最小内核,掌握Python解析器的核心实现逻辑,学习世界上最优秀的源码设计之一.
以代码是一个MicroPython列表对象的实现,包括了列表的基本操作如创建、打印、扩展、排序、索引访问等。代码中包含了大量的注释,用于解释每个函数的作用和实现细节。这些注释对于理解MicroPython列表对象的工作原理非常有帮助。
#include <string.h>
#include <assert.h>
// 导入MicroPython对象列表相关的头文件
#include "py/objlist.h"
#include "py/runtime.h"
#include "py/stackctrl.h"
// 定义最小分配的列表大小
#define LIST_MIN_ALLOC 4
// 列表对象的打印函数
static void list_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) {
mp_obj_list_t *o = MP_OBJ_TO_PTR(o_in); // 将对象转换为列表对象指针
const char *item_separator = ", "; // 定义列表元素之间的分隔符
// 如果是JSON打印,获取配置的分隔符
if (!(MICROPY_PY_JSON && kind == PRINT_JSON)) {
kind = PRINT_REPR;
} else {
#if MICROPY_PY_JSON_SEPARATORS
item_separator = MP_PRINT_GET_EXT(print)->item_separator;
#endif
}
mp_print_str(print, "["); // 打印列表开始符号
for (size_t i = 0; i < o->len; i++) {
// 遍历列表中的每个元素
if (i > 0) {
mp_print_str(print, item_separator); // 打印元素分隔符
}
mp_obj_print_helper(print, o->items[i], kind); // 递归打印列表中的元素
}
mp_print_str(print, "]"); // 打印列表结束符号
}
// 从可迭代对象扩展列表
static mp_obj_t list_extend_from_iter(mp_obj_t list, mp_obj_t iterable) {
mp_obj_t iter = mp_getiter(iterable, NULL); // 获取可迭代对象的迭代器
mp_obj_t item;
while ((item = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) {
// 遍历迭代器中的元素
mp_obj_list_append(list, item); // 将元素添加到列表中
}
return list; // 返回扩展后的列表
}
// 创建一个新的列表对象
mp_obj_t mp_obj_list_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
(void)type_in; // 忽略传入的类型信息
mp_arg_check_num(n_args, n_kw, 0, 1, false); // 检查参数数量
// 根据参数数量进行不同的处理
switch (n_args) {
case 0: // 无参数,创建一个空列表
return mp_obj_new_list(0, NULL);
case 1: // 有一个参数,从可迭代对象创建列表
default: {
mp_obj_t list = mp_obj_new_list(0, NULL); // 创建一个空列表
return list_extend_from_iter(list, args[0]); // 从可迭代对象扩展列表
}
}
}
// 处理一元操作符
static mp_obj_t list_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in); // 将对象转换为列表对象指针
switch (op) {
case MP_UNARY_OP_BOOL: // 布尔运算,列表不为空则为True
return mp_obj_new_bool(self->len != 0);
case MP_UNARY_OP_LEN: // 获取列表长度
return MP_OBJ_NEW_SMALL_INT(self->len);
#if MICROPY_PY_SYS_GETSIZEOF
case MP_UNARY_OP_SIZEOF: // 获取列表占用的内存大小
size_t sz = sizeof(*self) + sizeof(mp_obj_t) * self->alloc;
return MP_OBJ_NEW_SMALL_INT(sz);
#endif
default: // 不支持的操作符
return MP_OBJ_NULL;
}
}
// 处理二元操作符
static mp_obj_t list_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
mp_obj_list_t *o = MP_OBJ_TO_PTR(lhs); // 将左侧对象转换为列表对象指针
switch (op) {
case MP_BINARY_OP_ADD: // 列表连接操作
if (!mp_obj_is_type(rhs, &mp_type_list)) {
return MP_OBJ_NULL; // 如果右侧不是列表类型,则不支持此操作
}
mp_obj_list_t *p = MP_OBJ_TO_PTR(rhs); // 将右侧对象转换为列表对象指针
mp_obj_list_t *s = list_new(o->len + p->len); // 创建新列表,长度为两个列表长度之和
mp_seq_cat(s->items, o->items, o->len, p->items, p->len, mp_obj_t); // 连接两个列表的元素
return MP_OBJ_FROM_PTR(s);
case MP_BINARY_OP_INPLACE_ADD: // 原地列表连接操作
list_extend(lhs, rhs); // 扩展左侧列表
return lhs; // 返回修改后的左侧列表
case MP_BINARY_OP_MULTIPLY: // 列表重复操作
mp_int_t n;
if (!mp_obj_get_int_maybe(rhs, &n)) {
return MP_OBJ_NULL; // 如果右侧不是整数,则不支持此操作
}
if (n < 0) {
n = 0; // 重复次数不能为负
}
mp_obj_list_t *s = list_new(o->len * n); // 创建新列表,长度为原列表长度乘以重复次数
mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items); // 重复原列表的元素
return MP_OBJ_FROM_PTR(s);
case MP_BINARY_OP_EQUAL: // 比较两个列表是否相等
case MP_BINARY_OP_LESS: // 比较两个列表是否满足小于关系
case MP_BINARY_OP_LESS_EQUAL: // 比较两个列表是否满足小于等于关系
case MP_BINARY_OP_MORE: // 比较两个列表是否满足大于关系
case MP_BINARY_OP_MORE_EQUAL: // 比较两个列表是否满足大于等于关系
{
if (!mp_obj_is_type(rhs, &mp_type_list)) {
if (op == MP_BINARY_OP_EQUAL) {
return mp_const_false; // 如果右侧不是列表类型,且操作符为等于,则返回False
}
return MP_OBJ_NULL; // 不支持的操作符
}
mp_obj_list_t *another = MP_OBJ_TO_PTR(rhs); // 将右侧对象转换为列表对象指针
bool res = mp_seq_cmp_objs(op, o->items, o->len, another->items, another->len); // 比较两个列表的元素
return mp_obj_new_bool(res); // 返回比较结果
}
default: // 不支持的操作符
return MP_OBJ_NULL;
}
}
// 列表的索引操作(获取、设置、删除)
static mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
// 如果要删除元素,value为MP_OBJ_NULL
if (value == MP_OBJ_NULL) {
// 删除操作
#if MICROPY_PY_BUILTINS_SLICE
if (mp_obj_is_type(index, &mp_type_slice)) {
// 处理切片删除
mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in);
mp_bound_slice_t slice;
if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) {
mp_raise_NotImplementedError(NULL);
}
mp_int_t len_adj = slice.start - slice.stop;
assert(len_adj <= 0);
mp_seq_replace_slice_no_grow(self->items, self->len, slice.start, slice.stop, self->items /*NULL*/, 0, sizeof(*self->items));
// 清除被删除的元素
mp_seq_clear(self->items, self->len + len_adj, self->len, sizeof(*self->items));
self->len += len_adj;
return mp_const_none;
}
#endif
mp_obj_t args[2] = {
self_in, index};
list_pop(2, args); // 调用pop函数进行删除
return mp_const_none;
} else if (value == MP_OBJ_SENTINEL) {
// 加载操作
mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in);
#if MICROPY_PY_BUILTINS_SLICE
if (mp_obj_is_type(index, &mp_type_slice)) {
// 处理切片加载
mp_bound_slice_t slice;
if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) {
return mp_seq_extract_slice(self->len, self->items, &slice);
}
mp_obj_list_t *res = list_new(slice.stop - slice.start);
mp_seq_copy(res->items, self->items + slice.start, res->len, mp_obj_t);
return MP_OBJ_FROM_PTR(res);
}
#endif
size_t index_val = mp_get_index(self->base.type