MicroPython 是一种适用于微控制器和其他受限环境的 Python 编程语言的实现。它旨在提供与 Python 3 语言的紧密兼容,同时考虑到内存和计算资源的限制。MicroPython 库是这门语言的核心组成部分,提供了一系列的模块和函数,使得开发者能够在硬件上执行各种任务。
下面将通过系列文章,逐一解读microPython,以便让读者了解掌握microPython的整个核心逻辑.,以便读者可以透过这个Python的最小内核,掌握Python解析器的核心实现逻辑,学习世界上最优秀的源码设计之一.
microPython Python最小内核源码解析
NI-motion运动控制c语言示例代码解析
python编程示例系列 python编程示例系列二
python的Web神器Streamlit
代码是一个C语言编写的微Python(MicroPython)字符串处理模块的一部分。它包含了字符串的打印、一元操作、索引和迭代等功能。代码中的注释已经翻译成中文,并补充了一些解释性的注释,以便更好地理解代码的功能和实现方式。
#include <string.h>
#include <assert.h>
#include "py/objstr.h"
#include "py/objlist.h"
#include "py/runtime.h"
#if MICROPY_PY_BUILTINS_STR_UNICODE
// 创建字符串迭代器对象
static mp_obj_t mp_obj_new_str_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf);
/******************************************************************************/
/* 字符串处理函数 */
// 打印带引号的字符串,用于输出JSON格式的字符串
static void uni_print_quoted(const mp_print_t *print, const byte *str_data, uint str_len) {
// 检查字符串中是否包含单引号和双引号,以便决定使用哪种引号包围字符串
bool has_single_quote = false;
bool has_double_quote = false;
for (const byte *s = str_data, *top = str_data + str_len; s < top; s++) {
if (*s == '\'') {
has_single_quote = true;
} else if (*s == '"') {
has_double_quote = true;
}
}
// 选择引号类型
unichar quote_char = '\'';
if (has_single_quote && !has_double_quote) {
quote_char = '"';
}
mp_printf(print, "%c", quote_char); // 打印引号
const byte *s = str_data, *top = str_data + str_len;
while (s < top) {
unichar ch;
ch = utf8_get_char(s);
s = utf8_next_char(s);
// 根据字符类型进行转义打印
if (ch == quote_char) {
mp_printf(print, "\\%c", quote_char);
} else if (ch == '\\') {
mp_print_str(print, "\\\\");
} else if (32 <= ch && ch <= 126) {
mp_printf(print, "%c", ch);
} else if (ch == '\n') {
mp_print_str(print, "\\n");
} else if (ch == '\r') {
mp_print_str(print, "\\r");
} else if (ch == '\t') {
mp_print_str(print, "\\t");
} else if (ch < 0x100) {
mp_printf(print, "\\x%02x", ch);
} else if (ch < 0x10000) {
mp_printf(print, "\\u%04x", ch);
} else {
mp_printf(print, "\\U%08x", ch);
}
}
mp_printf(print, "%c", quote_char); // 打印结束引号
}
// 打印字符串,根据不同的打印类型进行处理
static void uni_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
GET_STR_DATA_LEN(self_in, str_data, str_len);
#if MICROPY_PY_JSON
if (kind == PRINT_JSON) {
mp_str_print_json(print, str_data, str_len);
return;
}
#endif
if (kind == PRINT_STR) {
print->print_strn(print->data, (const char *)str_data, str_len);
} else {
uni_print_quoted(print, str_data, str_len);
}
}
// 一元操作函数,处理如布尔值、长度等操作
static mp_obj_t uni_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
GET_STR_DATA_LEN(self_in, str_data, str_len);
switch (op) {
case MP_UNARY_OP_BOOL:
return mp_obj_new_bool(str_len != 0);
case MP_UNARY_OP_LEN:
return MP_OBJ_NEW_SMALL_INT(utf8_charlen(str_data, str_len));
default:
return MP_OBJ_NULL; // 操作不支持
}
}
// 将索引值转换为指向其首字节的指针
const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, size_t self_len,
mp_obj_t index, bool is_slice) {
// 处理字节对象
if (type == &mp_type_bytes
#if MICROPY_PY_BUILTINS_BYTEARRAY
|| type == &mp_type_bytearray
#endif
) {
// 从objstr.c:str_index_to_ptr()中复制的代码
size_t index_val = mp_get_index(type, self_len, index, is_slice);
return self_data + index_val;
}
mp_int_t i;
// 从mp_get_index复制的代码,获取索引的整数值
if (mp_obj_is_small_int(index)) {
i = MP_OBJ_SMALL_INT_VALUE(index);
} else if (!mp_obj_get_int_maybe(index, &i)) {
mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("字符串索引必须是整数,而不是 %s"), mp_obj_get_type_str(index));
}
const byte *s, *top = self_data + self_len;
if (i < 0) {
// 处理负索引
for (s