MicroPython 是一种适用于微控制器和其他受限环境的 Python 编程语言的实现。它旨在提供与 Python 3 语言的紧密兼容,同时考虑到内存和计算资源的限制。MicroPython 库是这门语言的核心组成部分,提供了一系列的模块和函数,使得开发者能够在硬件上执行各种任务。
下面将通过系列文章,逐一解读microPython,以便让读者了解掌握microPython的整个核心逻辑.,以便读者可以透过这个Python的最小内核,掌握Python解析器的核心实现逻辑,学习世界上最优秀的源码设计之一.
microPython Python最小内核源码解析
NI-motion运动控制c语言示例代码解析
python编程示例系列 python编程示例系列二
python的Web神器Streamlit
这段代码是一个C语言实现的微型Python解释器的一部分,它定义了Python中的range
对象和其相关的操作,包括迭代器、打印、创建、长度计算、属性访问等。代码中使用了MicroPython的一些宏和函数来简化对象类型的定义和操作的实现。
#include <stdlib.h>
#include "py/runtime.h"
/******************************************************************************/
/* 范围迭代器 */
// 定义一个结构体,用于表示范围迭代器对象
typedef struct _mp_obj_range_it_t {
mp_obj_base_t base; // 继承自基础对象
// TODO 将这些值改为通用对象或其他类型
mp_int_t cur; // 当前迭代的值
mp_int_t stop; // 范围的结束值
mp_int_t step; // 步长
} mp_obj_range_it_t;
// 定义一个函数,用于获取迭代器的下一个元素
static mp_obj_t range_it_iternext(mp_obj_t o_in) {
mp_obj_range_it_t *o = MP_OBJ_TO_PTR(o_in); // 将对象转换为迭代器结构体指针
// 判断当前值是否在范围内
if ((o->step > 0 && o->cur < o->stop) || (o->step < 0 && o->cur > o->stop)) {
mp_obj_t o_out = MP_OBJ_NEW_SMALL_INT(o->cur); // 创建一个新的小整数对象作为输出
o->cur += o->step; // 根据步长更新当前值
return o_out; // 返回当前值
} else {
return MP_OBJ_STOP_ITERATION; // 表示迭代结束
}
}
// 定义一个宏,用于创建范围迭代器对象类型
static MP_DEFINE_CONST_OBJ_TYPE(
mp_type_range_it,
MP_QSTR_iterator, // 字符串常量 "iterator"
MP_TYPE_FLAG_ITER_IS_ITERNEXT, // 标记为迭代器
iter, range_it_iternext // 迭代器操作函数
);
// 定义一个函数,用于创建新的范围迭代器对象
static mp_obj_t mp_obj_new_range_iterator(mp_int_t cur, mp_int_t stop, mp_int_t step, mp_obj_iter_buf_t *iter_buf) {
assert(sizeof(mp_obj_range_it_t) <= sizeof(mp_obj_iter_buf_t)); // 确保迭代器结构体大小不超过迭代缓冲区大小
mp_obj_range_it_t *o = (mp_obj_range_it_t *)iter_buf; // 将迭代缓冲区转换为迭代器结构体指针
o->base.type = &mp_type_range_it; // 设置对象类型
o->cur = cur; // 设置当前值
o->stop = stop; // 设置结束值
o->step = step; // 设置步长
return MP_OBJ_FROM_PTR(o); // 返回迭代器对象
}
/******************************************************************************/
/* 范围 */
// 定义一个结构体,用于表示范围对象
typedef struct _mp_obj_range_t {
mp_obj_base_t base; // 继承自基础对象
// TODO 将这些值改为通用对象或其他类型
mp_int_t start; // 范围的起始值
mp_int_t stop; // 范围的结束值
mp_int_t step; // 步长
} mp_obj_range_t;
// 定义一个函数,用于打印范围对象
static void range_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
(void)kind; // 不使用kind参数
mp_obj_range_t *self = MP_OBJ_TO_PTR(self_in); // 将对象转换为范围结构体指针
mp_printf(print, "range(" INT_FMT ", " INT_FMT "", self->start, self->stop); // 打印起始和结束值
if (self->step == 1) {
mp_print_str(print, ")");
} else {
mp_printf(print, ", " INT_FMT ")", self->step); // 如果步长不为1,打印步长
}
}
// 定义一个函数,用于创建新的范围对象
static mp_obj_t range_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, 3, false); // 检查参数数量
mp_obj_range_t *o = mp_obj_malloc(mp_obj_range_t, type); // 分配范围对象内存
o->start = 0; // 默认起始值为0
o->step = 1; // 默认步长为1
if (n_args == 1) {
o->stop = mp_obj_get_int(args[0]); // 如果只有一个参数,则是结束值
} else {
o->start = mp_obj_get_int(args[0]); // 如果有两个参数,第一个是起始值
o->stop = mp_obj_get_int(args[1]); // 第二个是结束值
if (n_args == 3) {
o->step = mp_obj_get_int(args[2]); // 如果有三个参数,第三个是步长
if (o->step == 0) {
mp_raise_ValueError(MP_ERROR_TEXT("步长不能为0")); // 如果步长为0,抛出值错误
}
}
}
return MP_OBJ_FROM_PTR(o); // 返回范围对象
}
// 定义一个函数,用于计算范围的长度
static mp_int_t range_len(mp_obj_range_t *self) {
// 计算长度时需要考虑步长不为1和步长为负数的情况
mp_int_t len = self->stop - self->start + self->step;
if (self->step > 0) {
len -= 1;
} else {
len += 1;
}
len = len / self->step;
if (len < 0) {
len = 0;
}
return len; // 返回计算后的长度
}
// 定义一个函数,用于处理范围对象的一元操作
static