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'
|