MicroPython 编程最吸引人的方面之一是它与近二十年来在桌面环境中广泛使用的 CPython 相似。由于几乎相同的语法和设计范例,在嵌入式和桌面开发环境之间移动几乎是无缝的体验。这在物联网时代是非常可取的,在这个时代,来自嵌入式电子产品的数据必须可以在众多平台上访问,包括移动、桌面和云。如果工具和编程语言的变化最小化,开发人员可以保持精简,产品开发周期可以缩短。也就是说,与桌面计算相比,嵌入式硬件环境的本质要求 MicroPython 和 CPython 之间存在一些并非微不足道的差异。
注:CPython 是用 C 语言实现的 Python 解释器,也是官方的并且是最广泛使用的 Python 解释器。除了 CPython 以外,还有用 JAVA 实现的 Jython 和用.NET 实现的 IronPython,使 Python 方便地和 JAVA 程序、.NET 程序集成。另外还有一些实验性的 Python 解释器比如 PyPy。
CPython 是使用字节码的解释器,任何程序源代码在执行之前先要编译成字节码。它还有和几种其它语言(包括 C 语言)交互的外部函数接口。
嵌入式电子生态系统在许多方面受到限制,而台式机或服务器则没有。首先,它们受到能源消耗的限制。许多嵌入式设备都是电池供电的,因此延长电池寿命在性能方面受到限制。台式计算机可能以几千兆赫兹的速度运行,而微控制器充其量只能以几十兆赫兹的速度运行。受限内存和存储也往往是显着影响 CPython 和 MicroPython 之间差异的限制因素。由于内存仅以千字节或兆字节为单位,内存密集型功能通常会减少甚至完全从 MicroPython 实现中删除。了解差异对于希望避免调试嵌入式代码的许多令人沮丧的时间的开发人员来说非常重要。
CPython 开发人员可以访问数百个预构建模块,只需一行代码即可将这些模块轻松添加到他们的项目中。这些模块消除了在寻求向项目添加功能时重新发明轮子的需要。但是,许多模块在内存利用率方面可能非常大。MicroPython 要么消除模块,要么提供专为嵌入式平台设计的模块的定制实现。还有嵌入式平台独有的模块,例如与通用 I/O (GPIO) 引脚的接口。
CPython 使用自动引用计数作为其内存管理方式,而 MicroPython 使用垃圾收集。从实际的角度来看,当需要分配内存时,MicroPython 将尝试在堆上找到足够大小的内存块。如果失败,MicroPython 将寻求释放内存中未使用或冗余的对象。这是一个通常以毫秒为单位的过程。或者,开发人员可以偶尔gc.collect()以预定的时间间隔运行以清理内存,以确保垃圾收集不会在代码的关键部分发生。
语法差异可能是让大多数开发人员陷入困境的差异类型,特别是如果您有任何重要的 CPython 经验,这可能会给您编程时带来某种“肌肉记忆”。
MicroPython 要求文字数字和关键字之间有空格;相比之下,CPython 则不然。
MicroPython 允许使用 := 赋值给理解变量;CPython 引发语法错误。
使 Python 对编码新手友好的设计特性之一是它处理数据类型(例如整数、布尔值、浮点数)的方式。在 Python 中,所有数据类型都是类,变量是类的实例。然而,MicroPython 并没有实现整个 CPython 对象数据模型。值得注意的差异包括缺少多重继承、__new__ 和 __del__特殊方法可能不起作用、方法解析顺序不同以及不支持元类。
MicroPython 中未实现异常链接。因此,MicroPython 无法跨程序的不同抽象层重新抛出异常。
内置类型的处理方式不同。例如,MicroPython 不支持删除数组。
在 Python 中,函数是对象并且具有一组定义的属性,可以通过函数调用访问这些属性。例如,所有函数都有一个内置属性__doc__,它返回函数源代码中定义的文档字符串。函数的用户定义属性在 CPython 中是可能的;但是,MicroPython 不支持它们。这样做是因为嵌入式系统中通常会遇到内存限制。
覆盖sys.stdin, sys.stdout, 和sys.stderr是不可能的。这些是解释器用于标准输入、输出和错误的文件对象。这就是我们向用户显示文本并从用户那里获取输入的方式。
未能加载的模块仍被注册为已加载。这是为了使模块处理更有效率。因此,加载不包含异常处理。在部署到生产环境之前,一定要在开发环境中测试代码!
该environ属性未实现。相反,开发人员必须使用getenv()、putenv()和unsetenv() 方法来设置和获取环境变量。请注意,该getenv() 方法只允许将一个参数传递给它。
该print()函数不会像 CPython 那样检查递归数据结构(例如,递归列表)。MicroPython 会检查堆栈使用情况,因此打印递归数据结构不会因堆栈溢出而导致崩溃。
方法的错误消息可能会显示意外的参数计数,因为 MicroPython 将“self”计为参数。确保在处理错误消息时牢记这一事实。
JSON(JavaScript 对象表示法)是一种流行的数据交换格式,许多物联网终端设备使用它来与云高效通信。如果 JSON 对象不可序列化,MicroPython JSON 模块不会抛出异常。
该struct 模块在 Python 值和表示为 Python 字节对象的 C 结构之间进行转换。这允许有效处理存储在文件中或来自传感器常用的网络连接或串行协议的二进制数据。不幸的是,该struct.pack(format, v1, v2)函数不进行检查以确保为其提供了正确数量的参数。这与 CPython 实现形成对比,后者确实检查参数计数。
未实现在数组中搜索整数的功能。因此,以下代码将导致错误:
import array as array a = array.array('i', [1, 2, 3, 4]) print(1 in a)
CPython 会打印false,而 MicroPython 会返回未实现的错误消息。
MicroPython 是一种功能强大且易于使用的编程语言,用于开发嵌入式应用程序。但是,与用于创建桌面和云原生应用程序的功能更丰富的 Python 实现相比,它是有限的。一些差异可能会在未来的 MicroPython 版本中得到修复,或者随着新功能被添加到 Python 的参考实现中,可能会出现新的差异。要查看 CPython 和 MicroPython 之间的最新差异,请务必在其网站上查看 MicroPython 的官方文档。