Langage de base¶
Generated Fri 19 Jun 2026 22:08:45 UTC
Classes¶
La méthode spéciale __del__ n’est pas implémentée pour les classes définies par l’utilisateur¶
Exemple de code
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__()
Exemple de code
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.
Exemple de code
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.
Exemple de code
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.
Exemple de code
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__'
|
L’ordre de résolution des méthodes (MRO) n’est pas conforme à CPython¶
Cause : Ordre de résolution des méthodes en profondeur d’abord, non exhaustif
Contournement : Évitez les hiérarchies de classes complexes avec héritage multiple et substitutions de méthodes complexes. Gardez à l’esprit que de nombreux langages ne supportent pas du tout l’héritage multiple.
Exemple de code
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)
|
La modification de noms des membres privés de classe n’est pas implémentée¶
Cause : Le compilateur MicroPython n’implémente pas la modification de noms pour les membres privés de classe.
Contournement : Évitez les collisions avec les noms globaux en ajoutant manuellement un préfixe unique au nom du membre privé de classe.
Exemple de code
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.
|
Lors de l’héritage de types natifs, appeler une méthode dans __init__(self, ...) avant super().__init__() lève une AttributeError (ou provoque une erreur de segmentation si MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG n’est pas activé).¶
Cause : MicroPython ne possède pas de méthodes __new__ et __init__ séparées dans les types natifs.
Contournement : Appelez super().__init__() en premier.
Exemple de code
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
|
Lors de l’héritage de plusieurs classes, super() n’appelle qu’une seule classe¶
Cause : Voir L’ordre de résolution des méthodes (MRO) n’est pas conforme à CPython
Contournement : Voir L’ordre de résolution des méthodes (MRO) n’est pas conforme à CPython
Exemple de code
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__
|
Appeler une propriété getter via super() dans une sous-classe retourne un objet property, et non la valeur¶
Exemple de code
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.
Exemple de code
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
|
Fonctions¶
Les messages d’erreur pour les méthodes peuvent afficher des nombres d’arguments inattendus¶
Cause : MicroPython compte « self » comme un argument.
Contournement : Interprétez les messages d’erreur en tenant compte de cette information.
Exemple de code
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
|
Les objets fonction ne possèdent pas l’attribut __module__¶
Cause : MicroPython est optimisé pour réduire la taille du code et l’utilisation de la RAM.
Contournement : Utilisez sys.modules[function.__globals__['__name__']] pour les modules non intégrés.
Exemple de code
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__'
|
Les attributs définis par l’utilisateur pour les fonctions ne sont pas pris en charge¶
Cause : MicroPython est fortement optimisé pour l’utilisation de la mémoire.
Contournement : Utilisez un dictionnaire externe, par ex. FUNC_X[f] = 0.
Exemple de code
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'
|
Générateur¶
Le gestionnaire de contexte __exit__() n’est pas appelé dans un générateur qui ne s’exécute pas jusqu’à la fin¶
Exemple de code
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
|
Environnement d’exécution¶
Les variables locales ne sont pas incluses dans le résultat de locals()¶
Cause : MicroPython ne maintient pas un environnement local symbolique ; il est optimisé sous forme d’un tableau de cases. Ainsi, les variables locales ne sont pas accessibles par nom.
Exemple de code
def test():
val = 2
print(locals())
test()
CPython output: | MicroPython output: |
{'val': 2}
| {'test': <function test at 0x7f5d74c05260>, '__name__': '__main__', '__file__': '<stdin>'}
|
Le code exécuté dans la fonction eval() n’a pas accès aux variables locales¶
Cause : MicroPython ne maintient pas un environnement local symbolique ; il est optimisé sous forme d’un tableau de cases. Ainsi, les variables locales ne sont pas accessibles par nom. En pratique, eval(expr) dans MicroPython est équivalent à eval(expr, globals(), globals()).
Exemple de code
val = 1
def test():
val = 2
print(val)
eval("print(val)")
test()
CPython output: | MicroPython output: |
2
2
| 2
1
|
f-strings¶
Les f-strings ne supportent pas la concaténation avec des littéraux adjacents si ceux-ci contiennent des accolades¶
Cause : MicroPython est optimisé pour l’espace de code.
Contournement : Utilisez l’opérateur + entre les chaînes littérales lorsqu’elles ne sont pas toutes les deux des f-strings
Exemple de code
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
|
Les f-strings ne peuvent pas supporter les expressions nécessitant une analyse syntaxique pour résoudre des accolades et crochets imbriqués non équilibrés¶
Cause : MicroPython est optimisé pour l’espace de code.
Contournement : Utilisez toujours des accolades et crochets équilibrés dans les expressions à l’intérieur des f-strings
Exemple de code
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
|
Les f-strings ne supportent pas les conversions !a¶
Cause : MicroPython n’implémente pas ascii()
Contournement : Aucun
Exemple de code
f"{'unicode text'!a}"
CPython output: | MicroPython output: |
Traceback (most recent call last):
File "<stdin>", line 8
SyntaxError: invalid syntax
|
import¶
L’attribut __path__ d’un paquet est d’un type différent (chaîne unique au lieu d’une liste de chaînes) dans MicroPython¶
Cause : MicroPython ne prend pas en charge les paquets d’espaces de noms répartis sur le système de fichiers. De plus, le système d’importation de MicroPython est fortement optimisé pour une utilisation minimale de la mémoire.
Contournement : Les détails de la gestion des importations dépendent intrinsèquement de l’implémentation. Ne vous fiez pas à ces détails dans des applications portables.
Exemple de code
import modules
print(modules.__path__)
CPython output: | MicroPython output: |
['/home/runner/work/openmv-doc/openmv-doc/micropython/tests/cpydiff/modules']
| ../tests/cpydiff/modules
|
MicroPython ne prend pas en charge les paquets d’espaces de noms répartis sur le système de fichiers.¶
Cause : Le système d’importation de MicroPython est fortement optimisé pour la simplicité, une utilisation minimale de la mémoire et un overhead minimal lors des recherches dans le système de fichiers.
Contournement : N’installez pas dans des répertoires différents des modules appartenant au même paquet d’espace de noms. Pour MicroPython, il est recommandé d’avoir au maximum 3 composantes dans les chemins de recherche de modules : pour votre application courante, par utilisateur (accessible en écriture) et à l’échelle du système (non accessible en écriture).
Exemple de code
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'
|