Kernsprache

Generated Fri 19 Jun 2026 22:08:45 UTC

Klassen

Die spezielle Methode __del__ ist für benutzerdefinierte Klassen nicht implementiert

Beispielcode:

import gc


class Foo:
    def __del__(self):
        print("__del__")


f = Foo()
del f

gc.collect()

CPython output:

MicroPython output:

__del__

__init_subclass__ isn’t automatically called.

Cause: MicroPython does not currently implement PEP 487.

Workaround: Manually call __init_subclass__ after class creation if needed. e.g.:

class A(Base):
    pass
A.__init_subclass__()

Beispielcode:

class Base:
    @classmethod
    def __init_subclass__(cls):
        print(f"Base.__init_subclass__({cls.__name__})")


class A(Base):
    pass

CPython output:

MicroPython output:

Base.__init_subclass__(A)

__init_subclass__ isn’t an implicit classmethod.

Cause: MicroPython does not currently implement PEP 487. __init_subclass__ is not currently in the list of special-cased class/static methods.

Workaround: Decorate declarations of __init_subclass__ with @classmethod.

Beispielcode:

def regularize_spelling(text, prefix="bound_"):
    # for regularizing across the CPython "method" vs MicroPython "bound_method" spelling for the type of a bound classmethod
    if text.startswith(prefix):
        return text[len(prefix) :]
    return text


class A:
    def __init_subclass__(cls):
        pass

    @classmethod
    def manual_decorated(cls):
        pass


a = type(A.__init_subclass__).__name__
b = type(A.manual_decorated).__name__

print(regularize_spelling(a))
print(regularize_spelling(b))
if a != b:
    print("FAIL")

CPython output:

MicroPython output:

method
method
function
method
FAIL

MicroPython doesn’t support parameterized __init_subclass__ class customization.

Cause: MicroPython does not currently implement PEP 487. The MicroPython syntax tree does not include a kwargs node after the class inheritance list.

Workaround: Use class variables or another mechanism to specify base-class customizations.

Beispielcode:

class Base:
    @classmethod
    def __init_subclass__(cls, arg=None, **kwargs):
        cls.init_subclass_was_called = True
        print(f"Base.__init_subclass__({cls.__name__}, {arg=!r}, {kwargs=!r})")


class A(Base, arg="arg"):
    pass


# Regularize across MicroPython not automatically calling __init_subclass__ either.
if not getattr(A, "init_subclass_was_called", False):
    A.__init_subclass__()

CPython output:

MicroPython output:

Base.__init_subclass__(A, arg='arg', kwargs={})
Traceback (most recent call last):
  File "<stdin>", line 16, in <module>
TypeError: function doesn't take keyword arguments

__init_subclass__ can’t be defined a cooperatively-recursive way.

Cause: MicroPython does not currently implement PEP 487. The base object type does not have an __init_subclass__ implementation.

Workaround: Omit the recursive __init_subclass__ call unless it’s known that the grandparent also defines it.

Beispielcode:

class Base:
    @classmethod
    def __init_subclass__(cls, **kwargs):
        cls.init_subclass_was_called = True
        super().__init_subclass__(**kwargs)


class A(Base):
    pass


# Regularize across MicroPython not automatically calling __init_subclass__ either.
if not getattr(A, "init_subclass_was_called", False):
    A.__init_subclass__()

CPython output:

MicroPython output:

Traceback (most recent call last):
  File "<stdin>", line 22, in <module>
  File "<stdin>", line 13, in __init_subclass__
AttributeError: 'super' object has no attribute '__init_subclass__'

Die Methodenauflösungsreihenfolge (MRO) entspricht nicht CPython

Ursache: Tiefenorientierte, nicht erschöpfende Methodenauflösungsreihenfolge

Abhilfe: Vermeiden Sie komplexe Klassenhierarchien mit Mehrfachvererbung und komplexen Methodenüberschreibungen. Bedenken Sie, dass viele Sprachen Mehrfachvererbung überhaupt nicht unterstützen.

Beispielcode:

class Foo:
    def __str__(self):
        return "Foo"


class C(tuple, Foo):
    pass


t = C((1, 2, 3))
print(t)

CPython output:

MicroPython output:

Foo
(1, 2, 3)

Name-Mangling für private Klassenmitglieder ist nicht implementiert

Ursache: Der MicroPython-Compiler implementiert kein Name-Mangling für private Klassenmitglieder.

Abhilfe: Vermeiden Sie Konflikte mit globalen Namen, indem Sie dem Namen des privaten Klassenmitglieds manuell ein eindeutiges Präfix hinzufügen.

Beispielcode:

def __print_string(string):
    print(string)


class Foo:
    def __init__(self, string):
        self.string = string

    def do_print(self):
        __print_string(self.string)


example_string = "Example String to print."

class_item = Foo(example_string)
print(class_item.string)

class_item.do_print()

CPython output:

MicroPython output:

Example String to print.
Traceback (most recent call last):
  File "<stdin>", line 26, in <module>
  File "<stdin>", line 18, in do_print
NameError: name '_Foo__print_string' is not defined. Did you mean: '__print_string'?
Example String to print.
Example String to print.

Beim Erben nativer Typen führt der Aufruf einer Methode in __init__(self, ...) vor super().__init__() zu einem AttributeError (oder zu einem Segfault, wenn MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG nicht aktiviert ist).

Ursache: MicroPython hat keine getrennten __new__- und __init__-Methoden in nativen Typen.

Abhilfe: Rufen Sie zuerst super().__init__() auf.

Beispielcode:

class L1(list):
    def __init__(self, a):
        self.append(a)


try:
    L1(1)
    print("OK")
except AttributeError:
    print("AttributeError")


class L2(list):
    def __init__(self, a):
        super().__init__()
        self.append(a)


try:
    L2(1)
    print("OK")
except AttributeError:
    print("AttributeError")

CPython output:

MicroPython output:

OK
OK
AttributeError
OK

Bei der Vererbung von mehreren Klassen ruft super() nur eine Klasse auf

Ursache: Siehe Die Methodenauflösungsreihenfolge (MRO) entspricht nicht CPython

Abhilfe: Siehe Die Methodenauflösungsreihenfolge (MRO) entspricht nicht CPython

Beispielcode:

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()

CPython output:

MicroPython output:

D.__init__
B.__init__
C.__init__
A.__init__
D.__init__
B.__init__
A.__init__

Das Aufrufen einer super()-Getter-Eigenschaft in einer Unterklasse gibt ein Property-Objekt zurück, nicht den Wert

Beispielcode:

class A:
    @property
    def p(self):
        return {"a": 10}


class AA(A):
    @property
    def p(self):
        return super().p


a = AA()
print(a.p)

CPython output:

MicroPython output:

{'a': 10}
<property>

Exceptions

Throwing a derived exception class instance in its __init__ without first calling super().__init__ is a TypeError

Cause: In MicroPython, an object is incompletely constructed if it does not call its superclass init function or return normally from its __init__. This prevents its usage in some circumstances.

Workaround: Call the superclass __init__ method before raising the exception.

Beispielcode:

class C(Exception):
    def __init__(self):
        raise self


class C1(Exception):
    def __init__(self):
        super().__init__()
        raise self


try:
    C()
except Exception as e:
    print(type(e).__name__)

try:
    C1()
except Exception as e:
    print(type(e).__name__)

CPython output:

MicroPython output:

C
C1
TypeError
C1

Funktionen

Fehlermeldungen für Methoden können unerwartete Argumentanzahlen anzeigen

Ursache: MicroPython zählt „self“ als Argument.

Abhilfe: Interpretieren Sie Fehlermeldungen unter Berücksichtigung der obigen Informationen.

Beispielcode:

try:
    [].append()
except Exception as e:
    print(e)

CPython output:

MicroPython output:

list.append() takes exactly one argument (0 given)
function takes 2 positional arguments but 1 were given

Funktionsobjekte haben kein __module__-Attribut

Ursache: MicroPython ist auf reduzierte Codegröße und RAM-Verbrauch optimiert.

Abhilfe: Verwenden Sie sys.modules[function.__globals__['__name__']] für Nicht-Einbaumodule.

Beispielcode:

def f():
    pass


print(f.__module__)

CPython output:

MicroPython output:

__main__
Traceback (most recent call last):
  File "<stdin>", line 13, in <module>
AttributeError: 'function' object has no attribute '__module__'

Benutzerdefinierte Attribute für Funktionen werden nicht unterstützt

Ursache: MicroPython ist stark auf Speicherverbrauch optimiert.

Abhilfe: Verwenden Sie ein externes Dictionary, z. B. FUNC_X[f] = 0.

Beispielcode:

def f():
    pass


f.x = 0
print(f.x)

CPython output:

MicroPython output:

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

Generator

__exit__() des Kontextmanagers wird in einem Generator, der nicht bis zum Ende läuft, nicht aufgerufen

Beispielcode:

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()

CPython output:

MicroPython output:

Enter
1
2
3
Exit
Enter
1
2
3

Laufzeit

Lokale Variablen sind nicht im Ergebnis von locals() enthalten

Ursache: MicroPython pflegt keine symbolische lokale Umgebung, sondern ist auf ein Array von Slots optimiert. Daher können lokale Variablen nicht über einen Namen abgerufen werden.

Beispielcode:

def test():
    val = 2
    print(locals())


test()

CPython output:

MicroPython output:

{'val': 2}
{'test': <function test at 0x7f5d74c05260>, '__name__': '__main__', '__file__': '<stdin>'}

Im eval()-Aufruf ausgeführter Code hat keinen Zugriff auf lokale Variablen

Ursache: MicroPython pflegt keine symbolische lokale Umgebung, sondern ist auf ein Array von Slots optimiert. Daher können lokale Variablen nicht über einen Namen abgerufen werden. Im Wesentlichen entspricht eval(expr) in MicroPython eval(expr, globals(), globals()).

Beispielcode:

val = 1


def test():
    val = 2
    print(val)
    eval("print(val)")


test()

CPython output:

MicroPython output:

2
2
2
1

f-strings

f-Strings unterstützen keine Verkettung mit benachbarten Literalen, wenn diese geschweifte Klammern enthalten

Ursache: MicroPython ist auf Codespeicherplatz optimiert.

Abhilfe: Verwenden Sie den +-Operator zwischen Zeichenkettenliteralen, wenn nicht beide f-Strings sind

Beispielcode:

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

CPython output:

MicroPython output:

aa1
1ab
a{}a1
1a{}b
aa1
1ab
Traceback (most recent call last):
  File "<stdin>", line 12, in <module>
IndexError: tuple index out of range

f-Strings können keine Ausdrücke unterstützen, die zum Auflösen unausgeglichener verschachtelter geschweifte Klammern und eckiger Klammern geparst werden müssen

Ursache: MicroPython ist auf Codespeicherplatz optimiert.

Abhilfe: Verwenden Sie in Ausdrücken innerhalb von f-Strings stets ausgeglichene geschweifte Klammern und eckige Klammern

Beispielcode:

print(f"{'hello { world'}")
print(f"{'hello ] world'}")

CPython output:

MicroPython output:

hello { world
hello ] world
Traceback (most recent call last):
  File "<stdin>", line 9
SyntaxError: invalid syntax

f-Strings unterstützen keine !a-Konvertierungen

Ursache: MicroPython implementiert ascii() nicht

Abhilfe: Keine

Beispielcode:

f"{'unicode text'!a}"

CPython output:

MicroPython output:

Traceback (most recent call last):
  File "<stdin>", line 8
SyntaxError: invalid syntax

import

Das __path__-Attribut eines Pakets hat in MicroPython einen anderen Typ (einzelne Zeichenkette statt einer Liste von Zeichenketten)

Ursache: MicroPython unterstützt keine auf das Dateisystem aufgeteilten Namespace-Pakete. Darüber hinaus ist das Importsystem von MicroPython stark auf minimalen Speicherverbrauch optimiert.

Abhilfe: Die Details der Importverarbeitung sind von der Implementierung abhängig. Verlassen Sie sich in portablen Anwendungen nicht auf solche Details.

Beispielcode:

import modules

print(modules.__path__)

CPython output:

MicroPython output:

['/home/runner/work/openmv-doc/openmv-doc/micropython/tests/cpydiff/modules']
../tests/cpydiff/modules

MicroPython unterstützt keine auf das Dateisystem aufgeteilten Namespace-Pakete.

Ursache: Das Importsystem von MicroPython ist stark auf Einfachheit, minimalen Speicherverbrauch und minimalen Dateisystem-Suchaufwand optimiert.

Abhilfe: Installieren Sie keine Module, die zum selben Namespace-Paket gehören, in verschiedenen Verzeichnissen. Für MicroPython wird empfohlen, höchstens 3-teilige Modulsuchpfade zu verwenden: für Ihre aktuelle Anwendung, benutzerspezifisch (schreibbar) und systemweit (nicht schreibbar).

Beispielcode:

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")

CPython output:

MicroPython output:

Two modules of a split namespace package imported
Traceback (most recent call last):
  File "<stdin>", line 14, in <module>
ImportError: no module named 'subpkg.bar'