microPython的源码解析之 objlist.c

本文深入解析MicroPython的源码,重点分析objlist.c中列表对象的实现,包括创建、扩展、排序等操作。通过详细解读代码和函数逻辑,帮助读者掌握MicroPython列表工作原理,理解Python解析器核心实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MicroPython 是一种适用于微控制器和其他受限环境的 Python 编程语言的实现。它旨在提供与 Python 3 语言的紧密兼容,同时考虑到内存和计算资源的限制。MicroPython 库是这门语言的核心组成部分,提供了一系列的模块和函数,使得开发者能够在硬件上执行各种任务。
下面将通过系列文章,逐一解读microPython,以便让读者了解掌握microPython的整个核心逻辑.,以便读者可以透过这个Python的最小内核,掌握Python解析器的核心实现逻辑,学习世界上最优秀的源码设计之一.

microPython 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

openwin_top

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值