内置类型

Generated Sat 23 Nov 2024 08:40:09 UTC

异常

所有异常都具有可读的 valueerrno 属性,不仅限于 StopIterationOSError

原因: MicroPython 优化了代码大小。

解决方法: 仅在 StopIteration 异常上使用 value,在 OSError 异常上使用 errno 。不要在其他异常上使用或依赖这些属性。

示例代码:

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'
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

未实现异常链接

示例代码:

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
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

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

原因: MicroPython 对内存使用进行了高度优化。

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

示例代码:

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

CPy输出:

uPy输出:

0
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

在 while 循环条件中的异常可能具有意外的行号

原因: 条件检查被优化为在循环体结束时进行,而报告的是该行号。

示例代码:

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
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

Exception.__init__ 方法不存在。

原因: 在 MicroPython 中并不完全支持对原生类进行子类化。

解决方法: 使用 super() 调用:

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

示例代码:

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


a = A()

CPy输出:

uPy输出:

/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

字节数组

使用不受支持的 RHS 进行数组切片赋值

示例代码:

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

CPy输出:

uPy输出:

bytearray(b'\x01\x02\x00\x00\x00')
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

bytes

bytes 对象支持 .format() 方法

原因: MicroPython 力求实现更规范的实现,因此如果 strbytes 都支持 __mod__() (% 运算符),那么支持 format() 对于两者都是有意义的。对于 __mod__ 的支持也可以编译出来,这样就只剩下了字节格式化的 format()

解决方法: 如果你关心与 CPython 的兼容性,请不要在 bytes 对象上使用 .format()

示例代码:

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

CPy输出:

uPy输出:

Traceback (most recent call last):
  File "<stdin>", line 7, in <module>
AttributeError: 'bytes' object has no attribute 'format'
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

未实现带有关键字的 bytes() 方法

解决方法: 将编码作为位置参数传递,例如 print(bytes('abc', 'utf-8'))

示例代码:

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

CPy输出:

uPy输出:

b'abc'
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

未实现step != 1的字节订阅

原因: MicroPython 对内存使用进行了高度优化。

解决方法: 对于这种非常罕见的操作,请使用显式循环。

示例代码:

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

CPy输出:

uPy输出:

b'13'
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

字典

字典键视图的行为不像集合。

原因: 未实现。

解决方法: 在使用集合操作之前,将键明确转换为集合。

示例代码:

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

CPy输出:

uPy输出:

{1}
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

float

uPy allows implicit conversion of objects in maths operations while CPython does not.

Workaround: Objects should be wrapped in float(obj) for compatibility with CPython.

示例代码:

class Test:
    def __float__(self):
        return 0.5


print(2.0 * Test())

CPy输出:

uPy输出:

Traceback (most recent call last):
  File "<stdin>", line 14, in <module>
TypeError: unsupported operand type(s) for *: 'float' and 'Test'
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

uPy 和 CPython 输出格式可能不同

示例代码:

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

CPy输出:

uPy输出:

-1e+01
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

int

bit_length 方法不存在。

原因: 未实现 bit_length 方法。

解决方法: 在 MicroPython 上避免使用此方法。

示例代码:

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

CPy输出:

uPy输出:

255 is 8 bits long.
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

int 派生类型的 int 转换不可用

解决方法: 除非真正需要,避免对内置类型进行子类化。更倾向于使用 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
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

list

未实现step != 1 的列表删除

解决方法: 对于此罕见操作,请使用显式循环。

示例代码:

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

CPy输出:

uPy输出:

[2, 4]
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

未实现 RHS 上不可迭代的列表切片存储

原因: RHS 受限于为元组或列表

解决方法: 在 RHS 上使用 list(<iter>) 将可迭代对象转换为列表

示例代码:

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

CPy输出:

uPy输出:

[0, 1, 2, 3, 20]
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

未实现step != 1 的列表存储

解决方法: 对于此罕见操作,请使用显式循环。

示例代码:

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

CPy输出:

uPy输出:

[5, 2, 6, 4]
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

memoryview

memoryview can become invalid if its target is resized

Cause: CPython prevents a bytearray or io.bytesIO object from changing size while there is a memoryview object that references it. MicroPython requires the programmer to manually ensure that an object is not resized while any memoryview references it.

In the worst case scenario, resizing an object which is the target of a memoryview can cause the memoryview(s) to reference invalid freed memory (a use-after-free bug) and corrupt the MicroPython runtime.

Workaround: Do not change the size of any bytearray or io.bytesIO object that has a memoryview assigned to it.

示例代码:

b = bytearray(b"abcdefg")
m = memoryview(b)
b.extend(b"hijklmnop")
print(b, bytes(m))

CPy输出:

uPy输出:

Traceback (most recent call last):
  File "<stdin>", line 11, in <module>
BufferError: Existing exports of data: object cannot be re-sized
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

str

开始/结束索引(例如 str.endswith(s, start))未实现

示例代码:

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

CPy输出:

uPy输出:

True
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

未实现属性/订阅

示例代码:

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

CPy输出:

uPy输出:

1
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

未实现带关键字的 str(…) 方法

解决方法: 直接输入编码格式。例如 print(bytes('abc', 'utf-8'))

示例代码:

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

CPy输出:

uPy输出:

abc
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

未实现str.ljust() 和 str.rjust()

原因: MicroPython 高度优化了内存使用。提供了简单的解决方法。

解决方法: 使用 "%-10s" % s 代替 s.ljust(10),使用 "% 10s" % s 代替 s.rjust(10)。或者,使用 "{:<10}".format(s)"{:>10}".format(s)

示例代码:

print("abc".ljust(10))

CPy输出:

uPy输出:

abc
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

将 None 作为 rsplit 的第一个参数(例如 str.rsplit(None, n))未实现

示例代码:

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

CPy输出:

uPy输出:

['a a', 'a']
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

带步长的下标!=1尚未实现

示例代码:

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

CPy输出:

uPy输出:

acegi
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found

元组

尚未实现步长不等于 1 的元组加载

示例代码:

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

CPy输出:

uPy输出:

(1, 3)
/bin/sh: 1: ../ports/unix/build-standard/micropython: not found