内置类型

Generated Thu 02 Sep 2021 01:44:06 UTC

异常

All exceptions have readable value and errno attributes, not just StopIteration and OSError .

原因: MicroPython is optimised to reduce code size.

解决方案: Only use value on StopIteration exceptions, and errno on OSError exceptions. Do not use or rely on these attributes on other exceptions.

样本代码:

e = Exception(1)
print(e.value)
print(e.errno)
												

CPy 输出:

uPy 输出:

Traceback (most recent call last):
  File "<stdin>", line 8, in <module>
AttributeError: 'Exception' object has no attribute 'value'
																
1
1
																

未实现异常链

样本代码:

try:
    raise TypeError
except TypeError:
    raise ValueError
												

CPy 输出:

uPy 输出:

Traceback (most recent call last):
  File "<stdin>", line 8, in <module>
TypeError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "<stdin>", line 10, in <module>
ValueError
																
Traceback (most recent call last):
  File "<stdin>", line 10, in <module>
ValueError:
																

不支持内置异常的用户定义属性

原因: MicroPython 对内存用法高度优化。

解决方案: 使用用户定义异常子类。

样本代码:

e = Exception()
e.x = 0
print(e.x)
												

CPy 输出:

uPy 输出:

0
																
Traceback (most recent call last):
  File "<stdin>", line 8, in <module>
AttributeError: 'Exception' object has no attribute 'x'
																

Exception in while loop condition may have unexpected line number

原因: Condition checks are optimized to happen at the end of loop body, and that line number is reported.

样本代码:

l = ["-foo", "-bar"]
i = 0
while l[i][0] == "-":
    print("iter")
    i += 1
												

CPy 输出:

uPy 输出:

iter
iter
Traceback (most recent call last):
  File "<stdin>", line 10, in <module>
IndexError: list index out of range
																
iter
iter
Traceback (most recent call last):
  File "<stdin>", line 12, in <module>
IndexError: list index out of range
																

Exception.__init__ method does not exist.

原因: Subclassing native classes is not fully supported in MicroPython.

解决方案: 调用使用 super() 代替:

class A(Exception):
    def __init__(self):
        super().__init__()
												

样本代码:

class A(Exception):
    def __init__(self):
        Exception.__init__(self)
a = A()
												

CPy 输出:

uPy 输出:

Traceback (most recent call last):
  File "<stdin>", line 18, in <module>
  File "<stdin>", line 15, in __init__
AttributeError: type object 'Exception' has no attribute '__init__'
																

bytearray

Array slice assignment with unsupported RHS

样本代码:

b = bytearray(4)
b[0:1] = [1, 2]
print(b)
												

CPy 输出:

uPy 输出:

bytearray(b'\x01\x02\x00\x00\x00')
																
Traceback (most recent call last):
  File "<stdin>", line 8, in <module>
NotImplementedError: array/bytes required on right side
																

bytes

bytes objects support .format() method

原因: MicroPython strives to be a more regular implementation, so if both str and bytes support __mod__() (the % operator), it makes sense to support format() for both too. Support for __mod__ can also be compiled out, which leaves only format() for bytes formatting.

解决方案: If you are interested in CPython compatibility, don’t use .format() on bytes objects.

样本代码:

print(b"{}".format(1))
												

CPy 输出:

uPy 输出:

Traceback (most recent call last):
  File "<stdin>", line 7, in <module>
AttributeError: 'bytes' object has no attribute 'format'
																
b'1'
																

未实现带关键字的 bytes()

解决方案: Pass the encoding as a positional parameter, e.g. print(bytes('abc', 'utf-8'))

样本代码:

print(bytes("abc", encoding="utf8"))
												

CPy 输出:

uPy 输出:

b'abc'
																
Traceback (most recent call last):
  File "<stdin>", line 7, in <module>
NotImplementedError: keyword argument(s) not yet implemented - use normal args instead
																

Bytes subscription with step != 1 not implemented

原因: MicroPython 对内存用法高度优化。

解决方案: Use explicit loop for this very rare operation.

样本代码:

print(b"123"[0:3:2])
												

CPy 输出:

uPy 输出:

b'13'
																
Traceback (most recent call last):
  File "<stdin>", line 7, in <module>
NotImplementedError: only slices with step=1 (aka None) are supported
																

dict

Dictionary keys view does not behave as a set.

原因: Not implemented.

解决方案: Explicitly convert keys to a set before using set operations.

样本代码:

print({1: 2, 3: 4}.keys() & {1})
												

CPy 输出:

uPy 输出:

{1}
																
Traceback (most recent call last):
  File "<stdin>", line 7, in <module>
TypeError: unsupported types for __and__: 'dict_view', 'set'
																

float

uPy and CPython outputs formats may differ

样本代码:

print("%.1g" % -9.9)
												

CPy 输出:

uPy 输出:

-1e+01
																
-10
																

int

bit_length method doesn’t exist.

原因: bit_length method is not implemented.

解决方案: Avoid using this method on MicroPython.

样本代码:

x = 255
print("{} is {} bits long.".format(x, x.bit_length()))
												

CPy 输出:

uPy 输出:

255 is 8 bits long.
																
Traceback (most recent call last):
  File "<stdin>", line 9, in <module>
AttributeError: 'int' object has no attribute 'bit_length'
																

No int conversion for int-derived types available

解决方案: Avoid subclassing builtin types unless really needed. Prefer https://en.wikipedia.org/wiki/Composition_over_inheritance .

样本代码:

class A(int):
    __add__ = lambda self, other: A(int(self) + other)
a = A(42)
print(a + a)
												

CPy 输出:

uPy 输出:

84
																
Traceback (most recent call last):
  File "<stdin>", line 14, in <module>
  File "<stdin>", line 10, in <lambda>
TypeError: unsupported types for __radd__: 'int', 'int'
																

list

List delete with step != 1 not implemented

解决方案: Use explicit loop for this rare operation.

样本代码:

l = [1, 2, 3, 4]
del l[0:4:2]
print(l)
												

CPy 输出:

uPy 输出:

[2, 4]
																
Traceback (most recent call last):
  File "<stdin>", line 8, in <module>
NotImplementedError:
																

List slice-store with non-iterable on RHS is not implemented

原因: RHS is restricted to be a tuple or list

解决方案: 使用 list(<iter>) on RHS to convert the iterable to a list

样本代码:

l = [10, 20]
l[0:1] = range(4)
print(l)
												

CPy 输出:

uPy 输出:

[0, 1, 2, 3, 20]
																
Traceback (most recent call last):
  File "<stdin>", line 8, in <module>
TypeError: object 'range' isn't a tuple or list
																

List store with step != 1 not implemented

解决方案: Use explicit loop for this rare operation.

样本代码:

l = [1, 2, 3, 4]
l[0:4:2] = [5, 6]
print(l)
												

CPy 输出:

uPy 输出:

[5, 2, 6, 4]
																
Traceback (most recent call last):
  File "<stdin>", line 8, in <module>
NotImplementedError:
																

str

Start/end indices such as str.endswith(s, start) not implemented

样本代码:

print("abc".endswith("c", 1))
												

CPy 输出:

uPy 输出:

True
																
Traceback (most recent call last):
  File "<stdin>", line 7, in <module>
NotImplementedError: start/end indices
																

Attributes/subscr not implemented

样本代码:

print("{a[0]}".format(a=[1, 2]))
												

CPy 输出:

uPy 输出:

1
																
Traceback (most recent call last):
  File "<stdin>", line 7, in <module>
NotImplementedError: attributes not supported yet
																

str(…) with keywords not implemented

解决方案: Input the encoding format directly. eg print(bytes('abc', 'utf-8'))

样本代码:

print(str(b"abc", encoding="utf8"))
												

CPy 输出:

uPy 输出:

abc
																
Traceback (most recent call last):
  File "<stdin>", line 7, in <module>
NotImplementedError: keyword argument(s) not yet implemented - use normal args instead
																

str.ljust() and str.rjust() not implemented

原因: MicroPython is highly optimized for memory usage. Easy workarounds available.

解决方案: Instead of s.ljust(10) use "%-10s" % s , instead of s.rjust(10) use "% 10s" % s . Alternatively, "{:<10}".format(s) or "{:>10}".format(s) .

样本代码:

print("abc".ljust(10))
												

CPy 输出:

uPy 输出:

abc
																
Traceback (most recent call last):
  File "<stdin>", line 7, in <module>
AttributeError: 'str' object has no attribute 'ljust'
																

None as first argument for rsplit such as str.rsplit(None, n) not implemented

样本代码:

print("a a a".rsplit(None, 1))
												

CPy 输出:

uPy 输出:

['a a', 'a']
																
Traceback (most recent call last):
  File "<stdin>", line 7, in <module>
NotImplementedError: rsplit(None,n)
																

Subscript with step != 1 is not yet implemented

样本代码:

print("abcdefghi"[0:9:2])
												

CPy 输出:

uPy 输出:

acegi
																
Traceback (most recent call last):
  File "<stdin>", line 7, in <module>
NotImplementedError: only slices with step=1 (aka None) are supported
																

tuple

Tuple load with step != 1 not implemented

样本代码:

print((1, 2, 3, 4)[0:4:2])
												

CPy 输出:

uPy 输出:

(1, 3)
																
Traceback (most recent call last):
  File "<stdin>", line 7, in <module>
NotImplementedError: only slices with step=1 (aka None) are supported