核心语言¶
Generated Wed 14 Aug 2024 09:10:45 UTC
f-strings 不支持与相邻文字的拼接,如果相邻文字包含大括号或是 f-strings¶
原因: MicroPython 优化了代码空间。
解决方法: 当其中一个或两者都是 f-strings 时,使用 + 操作符连接文字字符串
示例代码:
x, y = 1, 2
print("aa" f"{x}") # works
print(f"{x}" "ab") # works
print("a{}a" f"{x}") # fails
print(f"{x}" "a{}b") # fails
print(f"{x}" f"{y}") # fails
CPy输出: |
uPy输出: |
aa1
1ab
a{}a1
1a{}b
12
|
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found
|
f-strings 无法支持需要解析来解决不平衡嵌套大括号和方括号的表达式¶
原因: MicroPython 优化了代码空间。
解决方法: 在 f-strings 内的表达式中始终使用平衡的大括号和方括号
示例代码:
print(f'{"hello { world"}')
print(f'{"hello ] world"}')
CPy输出: |
uPy输出: |
hello { world
hello ] world
|
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found
|
不支持原始 f-strings¶
原因: MicroPython 优化了代码空间。
示例代码:
rf"hello"
CPy输出: |
uPy输出: |
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found
|
f-strings don’t support !a conversions¶
Cause: MicropPython does not implement ascii()
Workaround: None
示例代码:
f"{'unicode text'!a}"
CPy输出: |
uPy输出: |
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found
|
类¶
用户定义类的特殊方法 __del__ 未实现¶
示例代码:
import gc
class Foo:
def __del__(self):
print("__del__")
f = Foo()
del f
gc.collect()
CPy输出: |
uPy输出: |
__del__
|
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found
|
方法解析顺序(MRO)不符合 CPython¶
原因: 深度优先非穷尽方法解析顺序
解决方法: 避免具有多重继承和复杂方法重写的复杂类层次结构。请记住,许多语言根本不支持多重继承。
示例代码:
class Foo:
def __str__(self):
return "Foo"
class C(tuple, Foo):
pass
t = C((1, 2, 3))
print(t)
CPy输出: |
uPy输出: |
Foo
|
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found
|
从多个类继承时,super() 只调用一个类¶
原因: 见 方法解析顺序(MRO)不符合 CPython
解决方法: 见 方法解析顺序(MRO)不符合 CPython
示例代码:
class A:
def __init__(self):
print("A.__init__")
class B(A):
def __init__(self):
print("B.__init__")
super().__init__()
class C(A):
def __init__(self):
print("C.__init__")
super().__init__()
class D(B, C):
def __init__(self):
print("D.__init__")
super().__init__()
D()
CPy输出: |
uPy输出: |
D.__init__
B.__init__
C.__init__
A.__init__
|
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found
|
在子类中调用 super() getter 属性将返回一个属性对象,而不是值¶
示例代码:
class A:
@property
def p(self):
return {"a": 10}
class AA(A):
@property
def p(self):
return super().p
a = AA()
print(a.p)
CPy输出: |
uPy输出: |
{'a': 10}
|
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found
|
函数¶
方法的错误消息可能显示意外的参数计数¶
原因: MicroPython 将 “self” 作为参数计算。
示例代码:
try:
[].append()
except Exception as e:
print(e)
CPy输出: |
uPy输出: |
list.append() takes exactly one argument (0 given)
|
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found
|
函数对象没有 __module__
属性¶
原因: MicroPython 为了减少代码大小和 RAM 使用量进行了优化。
解决方法: 对于非内置模块,使用 sys.modules[function.__globals__['__name__']]
。
示例代码:
def f():
pass
print(f.__module__)
CPy输出: |
uPy输出: |
__main__
|
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found
|
不支持函数的用户定义属性¶
原因: MicroPython 对内存使用进行了高度优化。
解决方法: 使用外部字典,例如 FUNC_X[f] = 0
。
示例代码:
def f():
pass
f.x = 0
print(f.x)
CPy输出: |
uPy输出: |
0
|
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found
|
生成器¶
在不完全运行的生成器中,上下文管理器 __exit__() 不会被调用¶
示例代码:
class foo(object):
def __enter__(self):
print("Enter")
def __exit__(self, *args):
print("Exit")
def bar(x):
with foo():
while True:
x += 1
yield x
def func():
g = bar(0)
for _ in range(3):
print(next(g))
func()
CPy输出: |
uPy输出: |
Enter
1
2
3
Exit
|
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found
|
运行时¶
局部变量不包括在 locals() 结果中¶
原因: MicroPython 不维护符号局部环境,它被优化为一个插槽数组。因此,局部变量不能通过名称访问。
示例代码:
def test():
val = 2
print(locals())
test()
CPy输出: |
uPy输出: |
{'val': 2}
|
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found
|
在 eval() 函数中运行的代码无法访问局部变量¶
原因: MicroPython 不维护符号局部环境,它被优化为一个插槽数组。因此,局部变量不能通过名称访问。从效果上讲,MicroPython 中的 eval(expr)
相当于 eval(expr, globals(), globals())
。
示例代码:
val = 1
def test():
val = 2
print(val)
eval("print(val)")
test()
CPy输出: |
uPy输出: |
2
2
|
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found
|
导入¶
在 MicroPython 的 __init__.py 中不支持 __all__。¶
原因: 未实现。
解决方法: 直接在 __init__.py 中使用 from . import foo, bar
手动导入子模块。
示例代码:
from modules3 import *
foo.hello()
CPy输出: |
uPy输出: |
hello
|
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found
|
在 MicroPython 中,包的 __path__ 属性具有不同的类型(单个字符串而不是字符串列表)¶
Cause: MicroPython doesn’t support namespace packages split across filesystem. Beyond that, MicroPython’s import system is highly optimized for minimal memory usage.
解决方法: 导入处理的详细信息在本质上是与实现相关的。在可移植应用程序中不要依赖此类详细信息。
示例代码:
import modules
print(modules.__path__)
CPy输出: |
uPy输出: |
['/builds/openmv/openmv-doc/micropython/tests/cpydiff/modules']
|
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found
|
MicroPython doesn’t support namespace packages split across filesystem.¶
原因: MicroPython 的导入系统针对简单性、最小内存使用量和最小文件系统搜索开销进行了高度优化。
解决方法: 不要在不同目录中安装属于同一命名空间包的模块。对于 MicroPython,建议最多具有 3 个组件的模块搜索路径:对于当前应用程序、每个用户(可写)和系统范围(非可写)。
示例代码:
import sys
sys.path.append(sys.path[1] + "/modules")
sys.path.append(sys.path[1] + "/modules2")
import subpkg.foo
import subpkg.bar
print("Two modules of a split namespace package imported")
CPy输出: |
uPy输出: |
Two modules of a split namespace package imported
|
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found
|