这里写自定义目录标题
3. MicroPython 基础语法
作者: Dr. GAO
日期: 2025-1-25
淘宝店网址: https://genbotter.taobao.com
微信公众号: GenBotter
3.1. MicroPython和Python的区别
MicroPython 是 Python 3 语言的一个精简高效的实现版本,主要设计用于微控制器和嵌入式系统。假设你已经熟练掌握Python,你需要知道MicroPython与标准 Python 语法在大部分情况下是相似的,但也存在一些区别。
3.1.1. 内存管理与资源限制
变量声明: 在标准 Python 中,变量不需要事先声明,可直接赋值使用。而在 MicroPython 中,由于内存资源有限,对于一些可能占用大量内存的对象,如大列表、大字典等,需要更加谨慎地使用和及时释放内存,以避免内存泄漏。
内存回收: 标准 Python 有自动的垃圾回收机制,会自动回收不再使用的内存空间。MicroPython 的垃圾回收机制相对简单,在一些资源紧张的情况下,可能需要开发者手动触发垃圾回收来释放内存。
3.1.2. 模块与库
标准库差异: MicroPython 的标准库是标准 Python 标准库的一个子集,它只包含了在嵌入式系统中常用的一些模块,如time、machine等,缺少一些在桌面或服务器环境中使用的模块,如tkinter等图形界面库。
第三方库安装: 在标准 Python 中,可以使用pip命令方便地安装各种第三方库。而在 MicroPython 中,由于硬件资源的限制,安装第三方库的方式相对复杂,通常需要将库文件手动复制到设备的文件系统中,然后再进行导入使用。
3.1.3. 硬件交互
特定硬件模块: MicroPython 针对硬件交互提供了一些特定的模块和函数,如machine模块,用于操作微控制器的底层硬件,包括引脚配置、定时器、中断等。而这些在标准 Python 中是不存在的。
底层操作: 在 MicroPython 中,可以直接对硬件寄存器进行读写操作,实现对硬件的底层控制。例如,通过machine.Pin类可以设置引脚的输入输出模式、读取引脚状态等。而在标准 Python 中,通常需要通过操作系统提供的接口或特定的硬件驱动库来进行硬件操作。
3.1.4. 性能优化
代码优化: 由于 MicroPython 运行在资源受限的微控制器上,对代码的性能要求更高。因此,在 MicroPython 中,一些代码优化技巧更为重要,如尽量减少内存分配、避免使用过多的全局变量、使用高效的数据结构等。
特殊语法: MicroPython 提供了一些特殊的语法和函数来提高性能,如@micropython.native装饰器,可以将 Python 函数编译为机器码,提高执行速度。而在标准 Python 中,虽然也有一些优化工具和技术,但相对来说没有这么直接和针对性能的特殊语法。
3.1.5. 异常处理
异常类型: MicroPython 中的异常类型与标准 Python 基本相同,但在一些特定情况下,可能会抛出一些与硬件相关的异常,如machine.PinError等。
处理方式: 在 MicroPython 中,由于资源有限,异常处理需要更加谨慎,避免在异常处理中占用过多的内存和时间。例如,在一些关键的代码段中,可以使用try-except语句来捕获异常,并进行相应的处理,而在一些非关键的代码段中,可以根据实际情况选择是否进行异常处理。
3.2. 数据类型
MicroPython中基本的数据类型有Number(数字)、String(字符串)、List(列表)、Tuple(元组)、Dictionary(字典)等。
3.2.1. Number(数字)
MicroPython支持 int、float、bool、complex(复数)。当定义一个变量时,Number 对象被创建。 创建的Number对象,可以通过del语句进行删除。
a = 3
del a
注意:
- 可以同时为多个变量赋值,如a, b = 1, 2。
- 数值的除法(/)总是返回一个浮点数,如1/1,结果为1.0。
- 在混合计算时,MicroPython会把整型转换成为浮点型
3.2.1.1. int(整型)
MicroPython可以处理任意大小的整数(包括负整数),整数的表示方法和数学上的写法一样,如
1,100,-8080,0 ,……
MicroPython中用十六进制表示整数,如下:
0xff00,0xa5b3c3d2,……
3.2.1.2. float(浮点型)
浮点数就是小数。按科学计数法表示时,浮点数的小数点是可变的,如1.23×109和12.3×108是相等的。可以把10用e替代,1.23×10^9就是1.23e9,或是12.3e8,0.000012可以写成1.2e-5。
示例:
>>> a=1.25e3
>>> print(a)
1250.0
>>>
浮点数和整数在计算机内部存储方式不同,整数是精确的,而浮点数运算时会有四舍五入的误差。
3.2.1.3. bool(布尔型)
布尔值只有True、False两种值,非True则False,注意大小写
示例:
>>> flag=True
>>> num=2
>>> while flag:
print("genbotter")
num = num-1
if num==0:
flag=False
genbotter
genbotter
>>>
上述示例中while为一个循环语句,当flag为True时,循环执行后面的语句,if为一个判断语句,当num==0成立时,执行下面的语句(给flag赋值为False,while循环的条件不成立、跳出循环)。
3.2.1.4. complex(复数)
复数由实数部分和虚数部分构成,可以用a + bj,或者complex(a, b)表示, 复数的实部 a 和虚部 b 都可以是浮点型。
示例:
>>> complex(3,4)
(3+4j)
>>>
3.2.1.5. 数字类型转换
有时候,我们需要对数据内置的类型进行转换,具体如下:
int(x): 将x转换为一个整数。
float(x): 将x转换到一个浮点数。
complex(x):将x转换到一个复数,实数部分为 x,虚数部分为 0。
complex(x, y) :将 x 和 y 转换到一个复数,实数为x,虚数为 y。
x 和 y 可以是数字表达式。
3.2.2. String(字符串)
字符串是以双引号"或者单引号’括起来的任意文本(如’abc’,“xyz”)。其中," 或 '本身只是一种表示方式,不是字符串的一部分。因此,字符串’abc’只有abc这三个字符。
示例:
>>> str='ab,c'
>>> print(str)
ab,c
访问子字符串,可以使用方括号来截取字符串。
>>> str = 'genbotter'
>>> print(str[1])
e
>>> print(str[0:5])
genbo
>>>
可以截取字符串的一部分并与其他字符串拼接。
>>> str = 'genbotter'
>>> print(str[:7]+' stm32h723zgt6 board.')
genbott stm32h723zgt6 board.
>>>
3.2.3. List(列表)
列表(list)是MicroPython中最基本的数据结构。列表中的每个元素都分配一个索引,第一个索引是0,第二个是1,依次类推。在MicroPython中定义列表需要使用方括号,列表中的数据项都包含在方括号中,数据项之间使用逗号分隔。
3.2.3.1. 创建列表
创建列表时,列表中的数据可以是任意数据类型,甚至可以是不同类型的混合。示例:
>>> list_num_str=[0,1,2,'genbotter']
>>> print(list_num_str)
[0, 1, 2, 'genbotter']
>>>
列表中的数据除了基本的数据类型,还可以是其他复杂的数据结构。示例:
>>> board_info = [2024,12,24,['genbotter','stm32h723zg']]
>>> print(board_info)
[2024, 12, 24, ['genbotter', 'stm32h723zg']]
>>>
3.2.3.2. 操作列表
列表创建完成后,可以进行访问、修改、删除、插入等操作,即列表是可变的数据类型。
访问列表中的值,使用下标索引来访问列表中的值,同样也可以使用方括号的形式截取字符。示例:
>>> board = ['genbotter','stm32h723zgt6','mini']
>>> board[0]
'genbotter'
>>>
修改列表项,可以对列表的数据项进行修改。示例:
>>> board = ['genbotter','stm32h723zgt6','mini']
>>> board[1] = 'stm32f407vet6'
>>> print(board)
['genbotter', 'stm32f407vet6', 'mini']
>>>
删除列表中的元素,可以使用del或pop()函数来删除列表中指定位置的元素。示例:
>>> board = ['genbotter','stm32h723zgt6','mini']
>>> del board[2]
>>> print(board)
['genbotter', 'stm32h723zgt6']
>>>
在某一位置插入元素,用列表自带的 insert(i, x) 函数在位置 i 处插入元素 x,原来 i 位置及其后的元素依次后移,也可以使用append()方法在末尾添加元素。
示例:
>>> board =['genbotter']
>>> board.insert(1,'stm32h723zgt6')
>>> print(board)
['genbotter', 'stm32h723zgt6']
>>> board.append('gd32f130c8t6')
>>> print(board)
['genbotter', 'stm32h723zgt6', 'gd32f130c8t6']
>>>
常用的MicroPython列表脚本操作符,如下表:
MicroPython表达式 | 结果 | 描述 |
---|---|---|
len([1,2,3]) | 3 | 列表元素个数 |
[1,2,3]+[4,5,6] | [1,2,3,4,5,6] | 多个列表组合成一个列表 |
[‘ye!’] * 3 | [‘ye!’,‘ye!’,‘ye!’] | 重复若干个元素组成列表 |
3 in [1,2,3] | True | 判断元素是否存在于列表中 |
MicroPython列表操作的函数和方法,列表操作包含以下函数:
名称 | 描述 |
---|---|
cmp(list1, list2) | 比较两个列表的元素 |
len(list) | 返回列表元素个数 |
max(list) | 返回列表元素最大值 |
min(list) | 返回列表元素最小值 |
list(seq) | 将元组转换为列表 |
列表操作包含以下方法,如下表:
名称 | 描述 |
---|---|
list.append(obj) | 在列表末尾添加新的对象 |
list.count(obj) | 统计某个元素在列表中出现的次数 |
list.extend(seq) | 在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表) |
list.index(obj) | 从列表中找出某个值第一个匹配项的索引位置 |
list.insert(index, obj) | 将对象插入列表 |
list.pop(obj=list[-1]) | 移除列表中的一个元素(默认最后一个元素),并且返回该元素的值 |
list.remove(obj) | 移除列表中某个值的第一个匹配项 |
list.reverse() | 反向列表中元素 |
list.sort([func]) | 对原列表进行排序 |
3.2.4. Tuple(元组)
元组(tuple)和列表十分类似,只是元组和字符串一样是不可变的,即不能修改元组。正是由于元组不可变,一般用于MicroPython中定义一组不需要改变的值。
在MicroPython中定义元组使用圆括号,元组中的项目同样使用逗号分隔。
示例:
>>> tup = (1,3,5,7)
>>> print(tup)
(1, 3, 5, 7)
>>>
空的元组由一对空的圆括号组成,比如t=()
注意: 定义只有1个元素的元组时,必须要在这个元素后面跟一个逗号。示例:
>>> boards=('stm32f407vet6mini')
>>> type(boards)
<class 'str'>
>>> boards=('stm32f407vet6mini',)
>>> type(boards)
<class 'tuple'>
>>>
示例:(示例中,试图改变Tuple的内容,出错)
>>> tup = (1,2,'genbotter')
>>> print(tup)
(1, 2, 'genbotter')
>>> tup[0]
1
>>> tup[0]=3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>>
3.2.5. Dictionary(字典)
字典是一种无序的键值对(key-value)集合,其中键(key)必须是唯一且不可变的对象,如字符串、数字或元组,而值(value)可以是任何 Python 对象,包括数字、字符串、列表、字典等。通过键来访问对应的值,这种方式使得数据的查找和访问非常高效。
3.2.5.1. 创建字典
在MicroPython中创建字典使用花括号,字典中的键/值对之间使用逗号分隔,键和值之间用冒号分隔。示例:
>>> genbotter_boards ={'st-9':'stm32h723zgt6mini','st-5':'stm32h756vbt6mini'}
>>> print(genbotter_boards)
{'st-9': 'stm32h723zgt6mini', 'st-5': 'stm32h756vbt6mini'}
>>>
3.2.5.2. 操作字典
把数据放入dict,可以直接对单个键赋值的方法来将数据放入字典。示例:
>>> genbotter_boards ={'st-9':'stm32h723zgt6mini','st-5':'stm32h756vbt6mini'}
>>> genbotter_boards['st-1']='stm32f407vet6core'
>>> print(genbotter_boards)
{'st-9': 'stm32h723zgt6mini', 'st-5': 'stm32h756vbt6mini', 'st-1': 'stm32f407vet6core'}
>>>
由于一个key只对应一个value,所以,多次对一个key放入value,后面的值会把前面的值覆盖。示例:
>>> genbotter_boards ={'st-9':'stm32h723zgt6mini','st-5':'stm32h756vbt6mini'}
>>> print(genbotter_boards)
{'st-9': 'stm32h723zgt6mini', 'st-5': 'stm32h756vbt6mini'}
>>> genbotter_boards['st-9']='stm32h723zgt6'
>>> print(genbotter_boards)
{'st-9': 'stm32h723zgt6', 'st-5': 'stm32h756vbt6mini'}
>>>
删除键/值对,用pop(key)的方法删除一个键值对,对应的value也会从dict中删除,并且调用pop函数删除key-value时,该函数会把value作为pop函数的输出返回。示例:
>>> genbotter_boards ={'st-9':'stm32h723zgt6mini','st-5':'stm32h756vbt6mini'}
>>> print(genbotter_boards)
{'st-9': 'stm32h723zgt6mini', 'st-5': 'stm32h756vbt6mini'}
>>> genbotter_boards.pop('st-5')
'stm32h756vbt6mini'
>>> print(genbotter_boards)
{'st-9': 'stm32h723zgt6mini'}
>>>
3.3. 运算符
运算符是一种用于执行特定操作的符号或字符,用于对一个或多个操作数进行运算、比较、逻辑判断等操作,并返回相应的结果。在编程中,运算符是构建表达式的基本元素,通过运算符可以对变量、常量等进行各种数学运算、逻辑判断等操作,从而实现程序的各种功能。
MicroPython 运算符是在 MicroPython 编程语言中使用的运算符,与 Python 运算符基本相同,但在某些方面可能会有一些细微的差异或限制,主要基于 MicroPython 的设计目标和运行环境特点进行了一些优化和调整,使其更适合在微控制器等资源受限的设备上使用。它同样包括算术运算符、比较运算符、逻辑运算符、位运算符、赋值运算符、成员运算符和身份运算符等,本小节详细介绍MicroPython运算符。
3.3.1. 算术运算符
用于执行基本的数学运算,如加法、减法、乘法、除法等。在 MicroPython 中,这些运算符的用法与常规 Python 基本一致,但可能某些微控制器对浮点数运算的精度和速度有一定影响。
算术运算符如下表:
运算符 | 名称 | 说明 |
---|---|---|
+ | 加 | 两个对象相加 |
- | 减 | 定义一个负数,或两个对象相减 |
∗ | 乘 | 两数相乘或返回一个被重复若干次的字符串、列表、元组等 |
/ | 除 | x除以y |
// | 取整除 | 返回商的整数部分 |
% | 取余 | 返回除法的余数余 |
∗∗ | 幂 | 返回x的y次幂 |
示例:
>>> print(10//3)
3
>>> print(7//3)
2
>>> print(7%3)
1
>>> print(2**3)
8
>>>
3.3.2. 位运算符
用于对整数的二进制位进行操作,如按位与、按位或、按位异或等。在 MicroPython 中,位运算符在处理底层硬件寄存器或位掩码操作时非常有用。位运算符是把数字看作二进制来进行计算的,如5的二进制位为0101。有时候,在解析通信协议的时候还蛮有用的。
运算符 | 名称 | 说明 |
---|---|---|
<< | 左移 | 把<<左边的运算数的各二进制位全部左移若干位(由<<右边的数指定移动的位数),高位丢弃,低位补0 |
>> | 右移 | 把>>左边的运算数的各二进制位全部右移若干位,(由>>右边的数指定移动的位数 ),低位丢弃,高位补0 |
& | 按位与 | 参与运算的两个值,如果相应的两个位都为1,则对应位按位与运算的结果为1,否则为0 |
︱ | 按位或 | 两个数对应的二进制位有一个为1时,则对应位按位或运算的结果为1,否则为0 |
^ | 按位异或 | 两个数对应的二进制位不相同时,则该对应位按位异或运算的结果为1,否则为0 |
~ | 按位取反 | 每个二进制位取反,即把1变为0,把0变为1。 |
3.3.3. 比较运算符
用于比较两个值的大小或是否相等,返回布尔值(运算的结果为 True 或 False)。在 MicroPython 中,比较运算符常用于条件判断语句,如if语句,根据比较结果来决定程序的执行流程。
运算符 | 名称 | 说明 |
---|---|---|
< | 小于 | 返回x是否小于y。若为真返回True,为假返回False |
> | 大于 | 返回x是否大于y |
<= | 小于等于 | 返回x是否小于或等于y |
>= | 大于等于 | 返回x是否大于或等于y |
== | 等于 | 比较是否相等 |
!= | 不等于 | 比较是否不相等 |
3.3.4. 逻辑运算符
用于对布尔值进行逻辑运算,如与、或、非等。在 MicroPython 中,逻辑运算符常用于组合多个条件判断,使程序能够根据复杂的逻辑关系执行相应的操作。
运算符 | 名称 | 说明 |
---|---|---|
not | 布尔“非” | not x;如果x为True,返回False,否则返回True |
and | 布尔“与” | x and y;x,y都为True返回True,否则返回False |
or | 布尔“或” | x or y;x,y都为False返回False,否则返回True |
3.3.5. 赋值运算符
用于将一个值赋给一个变量。在 MicroPython 中,赋值运算符除了基本的=赋值外,还有一些复合赋值运算符,如+=、-=等,它们可以简化代码并提高执行效率。
运算符 | 名称 | 说明 |
---|---|---|
= | 简单的赋值运算符 | c = 10 将10赋值给c |
+= | 加法赋值运算符 | c += a 等效于 c = c + a |
-= | 减法赋值运算符 | c -= a 等效于 c = c - a |
∗= | 乘法赋值运算符 | c ∗= a 等效于 c = c ∗ a |
/= | 除法赋值运算符 | c /= a 等效于 c = c / a |
%= | 取模赋值运算符 | c %= a 等效于 c = c % a |
∗∗= | 幂赋值运算符 | c∗∗= a 等效于 c = c ∗∗ a |
//= | 取整除赋值运算符 | c //= a 等效于 c = c//a |
注意: 复合赋值运算符是一个整体,中间不能有空格。示例:
>>> a = 10
>>> a += 3
>>> a
13
>>> a + = 3
File "<stdin>", line 1
a + = 3
^
SyntaxError: invalid syntax
>>>
算术运算符和简单的赋值运算符“=”结合也可以构成复杂的赋值运算符。
3.3.6. 成员运算符
用于判断一个元素是否在一个序列(如列表、元组、字符串等)中。在 MicroPython 中,成员运算符常用于检查某个值是否存在于一个集合中,方便进行数据的查找和筛选。
运算符 | 名称 | 说明 |
---|---|---|
in | 成员资格 | 用于判断一个值是否在指定的序列(如列表、元组、字符串等)中,返回布尔值。例如:3 in [1, 2, 3]结果为True,“a” in "hello"结果为False。 |
not in | 成员资格的否定形式 | 用于判断一个值是否不在指定的序列中,返回布尔值。例如:3 not in [1, 2, 3]结果为False,“a” not in "hello"结果为True。 |
示例:
>>> 'e' in 'genbotter'
True
>>> 'e' not in 'genbotter'
False
>>>
3.3.7. 身份运算符
用于判断两个对象是否是同一个对象,即它们在内存中的地址是否相同。在 MicroPython 中,身份运算符在处理对象引用和内存管理时具有重要作用。
运算符 | 名称 | 说明 |
---|---|---|
is | 身份运算 | 用于判断两个对象是否是同一个对象,即它们在内存中的地址是否相同,返回布尔值。例如:a = [1, 2, 3];b = a;a is b结果为True。 |
is not | 身份运算的否定形式 | 用于判断两个对象是否不是同一个对象,返回布尔值。例如:a = [1, 2, 3];b = [1, 2, 3];a is not b结果为True。 |
示例:
>>> a = 'genbotter'
>>> b = a
>>> c = 'genbotter'
>>> a is b
True
>>> a is c
True
>>> c is a
True
>>> d = ('genbotter',)
>>> d is a
False
>>>
3.4. 条件判断和循环
在 MicroPython 中,条件判断和循环是控制程序流程的重要结构.
3.4.1. 条件判断
3.4.1.1. if语句
if语句是最基本的条件判断语句。它根据给定的条件表达式的值来决定是否执行一段代码块。如果条件表达式的值为True,则执行if语句后面的代码块;如果为False,则跳过该代码块。例如:
>>> x = 10
if x > 5:
print("x大于5")
x大于5
>>>
3.4.1.2. if-else语句
在if语句的基础上,if-else语句可以在条件不满足时执行另一段代码块。当if条件表达式的值为False时,将执行else后面的代码块。例如:
>>> x = 3
if x > 5:
print("x大于5")
else:
print("x小于等于5")
x小于等于5
>>>
3.4.1.3. if-elif-else语句
当需要判断多个条件时,可以使用if-elif-else语句。它会依次判断每个elif条件表达式,直到找到一个为True的条件,然后执行对应的代码块。如果所有条件都不满足,则执行else后面的代码块。例如:
>>> x = 7
if x > 10:
print("x大于10")
elif x > 5:
print("x大于5但小于等于10")
else:
print("x小于等于5")
x大于5但小于等于10
>>>
3.4.2. 循环
3.4.2.1. while循环
while循环会在条件表达式为True时重复执行一段代码块。在每次循环开始前,都会先检查条件表达式的值,如果为True,则执行循环体中的代码,然后再次检查条件,如此反复,直到条件表达式的值为False时停止循环。例如:
>>> i = 0
while i < 5:
print(i)
i += 1
0
1
2
3
4
>>>
3.4.2.2. for循环
for循环用于遍历可迭代对象(如列表、元组、字符串等)中的元素。它会依次取出可迭代对象中的每个元素,并执行循环体中的代码。例如:
>>> fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
apple
banana
cherry
>>>
3.4.2.3. range()函数
如果你需要遍历一系列的数字,可以使用内置函数range()。例如:
>>> for i in range(5):
print(i)
0
1
2
3
4
>>>
3.4.2.4. break
在循环中,可以使用break语句来立即终止循环,无论循环条件是否仍然为True。例如:
>>> # break示例
for i in range(10):
if i == 5:
break
print(i)
0
1
2
3
4
>>>
3.4.2.5. continue语句
而continue语句则用于跳过当前循环的剩余部分,直接进入下一次循环。例如:
>>> # continue示例
for i in range(10):
if i % 2 == 0:
continue
print(i)
1
3
5
7
9
>>>
3.4.2.6. pass语句
pass语句表示空语句,不做任何事情,一般用作占位语句,用来保持程序结构的完整性。例如:
from pyb import LED
led1 = LED(1)
led1.on()
while True:
pass
上面的代码,while循环时一个死循环,循环中的pass语句时一个空语句,整段代码表示让MicroPython开发板点亮LED1之后,就啥也不干、一直运行。
3.5. 函数
在 MicroPython 中,函数是一段可重复使用的代码块,它接受输入参数,执行特定的操作,并可以返回一个结果。
3.5.1. 函数的定义
除了MicroPython内建的函数,用户也可以使用def关键字来定义一个函数,后面跟着函数名、参数列表和冒号,函数体则缩进在下面。例如:
def add_numbers(a, b):
return a + b
一般格式如下:
def <函数名> (<参数1, 参数2, ……>) :
<函数体>
3.5.2. 函数的调用
通过函数名和参数列表来调用函数。调用函数时,实参的值会被传递给形参,然后函数体中的代码会被执行,最后返回结果。例如:
>>> def add_numbers(a,b):
return a+b
>>> result = add_numbers(3,5)
>>> print(result)
8
>>>
3.5.3. 函数的参数
形式参数:在函数定义中,参数列表中的参数称为形式参数,简称形参。它们只是占位符,用于接收调用函数时传递的值。
实际参数:在调用函数时,传递给函数的具体值称为实际参数,简称实参。实参可以是常量、变量、表达式等。
例如:
>>> def print_info(name, age): # name\age是形参
print(f"{name} is {age} years old.")
print_info("Alice", 25) #"Alice",25是实参,顺序要和形参一致
print_info(age=25, name="Alice") #age=25,name="Alice"是实参,顺序可以不一致
Alice is 25 years old.
Alice is 25 years old.
>>>
3.5.4. 函数的参数传递方式
值传递:对于不可变对象(如数字、字符串、元组等),在函数调用时,实参的值会被复制一份传递给形参,函数内部对形参的修改不会影响实参的值。
引用传递:对于可变对象(如列表、字典等),在函数调用时,实参的引用会被传递给形参,函数内部对形参的修改会直接影响实参的值。
3.5.5. 函数的返回值
使用return语句来返回函数的结果。当函数执行到return语句时,它会立即结束函数的执行,并将指定的值返回给调用者。如果函数没有显式地使用return语句,或者return后面没有跟任何值,那么函数将返回None。
例如:
>>> def xy(a,b):
... if a>b:
... return a
... elif a<b:
... return b
... else:
... return
>>> xy(5,6) #a=5,b=6
6
>>> a=xy(5,5)
>>> print(a)
None
>>>
3.5.6. 函数的作用域
局部作用域: 在函数内部定义的变量称为局部变量,它们只在函数内部有效,函数外部无法访问。当函数执行完毕后,局部变量会被销毁。例如:
>>> x = 0 #全局变量
>>> def deal_x():
... x = 6 #局部变量
... print(x)
...
>>> deal_x()
6
>>> print(x)
0
全局作用域: 在函数外部定义的变量称为全局变量,它们在整个程序中都有效,可以在函数内部和外部访问。但是,在函数内部如果要修改全局变量,需要使用global关键字进行声明。例如:
>>> x = 0 #声明全局变量
>>> def deal_x():
... global x #使用全局变量
... x = 15
... print(x)
...
...
...
>>> deal_x()
15
>>> print(x)
15
3.5.7. 函数的嵌套
在 MicroPython 中,函数可以嵌套定义,即一个函数内部可以定义另一个函数。内层函数可以访问外层函数的变量,但外层函数无法访问内层函数的变量。例如:
>>> def outer_function():
x = 10
def inner_function():
print(x)
inner_function()
>>> outer_function()
10
>inner_function()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'inner_function' is not defined
>>>
3.5.8. 内置函数
MicroPython 提供了许多内置函数,如print()用于输出信息,len()用于获取对象的长度,type()用于获取对象的类型等。这些内置函数可以直接在程序中使用,无需额外定义。
3.5.9. 函数的递归
函数可以调用自身,这种方式称为递归。递归函数通常用于解决可以分解为相似子问题的问题,如计算阶乘、斐波那契数列等。例如:
def factorial(n):
if n == 0 or n == 1:
return 1
else:
return n * factorial(n - 1)
3.6. 类
3.6.1. 类的基本结构
类使用class关键字定义,通常首字母大写,遵循驼峰命名法。类中可以包含属性和方法,属性用于存储数据,方法用于定义类的行为。
class MyClass:
def __init__(self):
self.x = 0 # 实例属性
def my_method(self): # 实例方法
print("This is a method.")
3.6.2. 构造函数__init__
__init__是一种特殊的方法,也称为构造函数。当创建类的实例时,它会自动被调用,用于初始化实例的属性。它的第一个参数必须是self,表示实例对象本身,后续参数可用于接收在实例化时传递的值。
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
3.6.3. 实例属性和方法
实例属性: 在类的方法中,通过self.属性名的方式定义的属性为实例属性。每个实例都有自己独立的一套实例属性,相互之间不会干扰。
实例方法: 在类中定义的普通方法称为实例方法,其第一个参数必须是self。通过实例调用实例方法时,self会自动指向该实例,从而可以在方法中访问和操作实例的属性。
class Circle:
def __init__(self, radius):
self.radius = radius
def area(self):
import math
return math.pi * self.radius ** 2
def circumference(self):
import math
return 2 * math.pi * self.radius
3.6.4. 类属性和类方法
类属性: 在类中方法之外定义的属性称为类属性,它属于整个类,所有实例共享同一个类属性。通过类名或实例都可以访问类属性。
类方法: 使用@classmethod装饰器修饰的方法称为类方法,其第一个参数通常为cls,表示类本身。类方法可以通过类名或实例调用,主要用于操作类属性或执行与类相关的操作。
class MyCounter:
count = 0 # 类属性
@classmethod
def increment(cls):
cls.count += 1
@classmethod
def get_count(cls):
return cls.count
3.6.5. 静态方法
使用@staticmethod装饰器修饰的方法称为静态方法,它不需要self或cls参数,与类和实例都没有直接关联,只是逻辑上属于该类。通常用于实现一些与类相关的辅助功能。
class MathUtils:
@staticmethod
def add(a, b):
return a + b
@staticmethod
def subtract(a, b):
return a - b
3.6.6. 类的继承
通过继承可以创建一个新类,新类继承了父类的属性和方法,并可在此基础上进行扩展和修改。使用class 子类名(父类名)的方式定义继承关系。
在子类的构造函数中,可以使用super()函数调用父类的构造函数,以初始化从父类继承的属性。
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
pass
class Dog(Animal):
def speak(self):
print(f"{self.name} says Woof!")
class Cat(Animal):
def speak(self):
print(f"{self.name} says Meow!")
3.6.7. 多态性
多态性是指不同的子类对象对同一方法有不同的实现方式。在 MicroPython 中,通过继承和方法重写实现多态性。
当调用同一个方法时,根据对象的实际类型,会执行相应子类中的方法实现。
def animal_speak(animal):
animal.speak()
dog = Dog("Fido")
cat = Cat("Kitty")
animal_speak(dog)
animal_speak(cat)
3.7. 参考
[1] MicroPython文档:http://micropython.com.cn/en/latet/develop/gettingstarted.html
[2] CSDN博客:https://xymgf.blog.csdn.net/article/details/106209755