核心语言¶
2021 年 7 月 9 日星期五 00:08:56 UTC 生成
班级¶
未为用户定义的类实现特殊方法 __del__¶
示例代码:
import gc
class Foo:
def __del__(self):
print("__del__")
f = Foo()
del f
gc.collect()
CPy 输出: |
uPy 输出: |
__del__
|
方法解析顺序 (MRO) 不符合 CPython¶
原因: 深度优先非穷尽方法解析顺序
解决方法: 避免具有多重继承和复杂方法覆盖的复杂类层次结构。请记住,许多语言根本不支持多重继承。
示例代码:
class Foo:
def __str__(self):
return "Foo"
class C(tuple, Foo):
pass
t = C((1, 2, 3))
print(t)
CPy 输出: |
uPy 输出: |
Foo
|
(1, 2, 3)
|
从多个类继承时 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__
|
D.__init__
B.__init__
A.__init__
|
在子类中调用 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}
|
<property>
|
职能¶
方法的错误消息可能会显示意外的参数计数¶
原因:MicroPython 将“自我”视为参数。
解决方法: 根据上述信息解释错误消息。
示例代码:
try:
[].append()
except Exception as e:
print(e)
CPy 输出: |
uPy 输出: |
append() takes exactly one argument (0 given)
|
function takes 2 positional arguments but 1 were given
|
函数对象没有__module__
属性¶
原因:MicroPython 针对减少代码大小和 RAM 使用进行了优化。
解决方法: 使用 sys.modules[function.__globals__['__name__']]
非内置模块。
示例代码:
def f():
pass
print(f.__module__)
CPy 输出: |
uPy 输出: |
__main__
|
Traceback (most recent call last):
File "<stdin>", line 13, in <module>
AttributeError: 'function' object has no attribute '__module__'
|
不支持函数的用户定义属性¶
原因: MicroPython 针对内存使用进行了高度优化。
解决方法: 使用外部字典,例如.FUNC_X[f] = 0
.
示例代码:
def f():
pass
f.x = 0
print(f.x)
CPy 输出: |
uPy 输出: |
0
|
Traceback (most recent call last):
File "<stdin>", line 13, in <module>
AttributeError: 'function' object has no attribute 'x'
|
发电机¶
上下文管理器 __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
|
Enter
1
2
3
|
运行¶
locals() 结果中不包含局部变量¶
原因: MicroPython 不维护符号本地环境,它针对插槽数组进行了优化。因此,不能通过名称访问局部变量。
示例代码:
def test():
val = 2
print(locals())
test()
CPy 输出: |
uPy 输出: |
{'val': 2}
|
{'test': <function test at 0x7fd179e25100>, '__name__': '__main__', '__file__': '<stdin>'}
|
在 eval() 函数中运行的代码无权访问局部变量¶
原因: MicroPython 不维护符号本地环境,它针对插槽数组进行了优化。因此,不能通过名称访问局部变量。实际上,eval(expr)
在 MicroPython 中相当于. eval(expr, globals(), globals())
示例代码:
val = 1
def test():
val = 2
print(val)
eval("print(val)")
test()
CPy 输出: |
uPy 输出: |
2
2
|
2
1
|
进口¶
__all__ 在 MicroPython 的 __init__.py 中不受支持。¶
原因: 未实施。
解决方法:在 __init__.py 中使用.from . import foo, bar
示例代码:
from modules3 import *
foo.hello()
CPy 输出: |
uPy 输出: |
hello
|
Traceback (most recent call last):
File "<stdin>", line 9, in <module>
NameError: name 'foo' isn't defined
|
包的 __path__ 属性在 MicroPython 中具有不同的类型(单个字符串而不是字符串列表)¶
原因: MicroPython 不支持跨文件系统拆分的命名空间包。除此之外,MicroPython 的导入系统针对最小内存使用量进行了高度优化。
解决方法: 导入处理的详细信息本质上取决于实现。不要依赖便携式应用程序中的这些细节。
示例代码:
import modules
print(modules.__path__)
CPy 输出: |
uPy 输出: |
['/home/micropython/micropython-docs/tests/cpydiff/modules']
|
../tests/cpydiff//modules
|
未能加载模块仍注册为已加载¶
原因: 为了使模块处理更有效,它没有用异常处理包装。
解决方法: 在生产使用前测试模块;在开发、使用或只是软或硬重置电路板。del sys.modules["name"]
示例代码:
import sys
try:
from modules import foo
except NameError as e:
print(e)
try:
from modules import foo
print("Should not get here")
except NameError as e:
print(e)
CPy 输出: |
uPy 输出: |
foo
name 'xxx' is not defined
foo
name 'xxx' is not defined
|
foo
name 'xxx' isn't defined
Should not get here
|
MicroPython 不支持跨文件系统拆分的命名空间包。¶
原因: 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
|
Traceback (most recent call last):
File "<stdin>", line 13, in <module>
ImportError: no module named 'subpkg.bar'
|