Limbajul de bază

Generated Fri 19 Jun 2026 22:08:45 UTC

Clase

Metoda specială __del__ nu este implementată pentru clasele definite de utilizator

Cod exemplu:

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

Cod exemplu:

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.

Cod exemplu:

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.

Cod exemplu:

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.

Cod exemplu:

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

Ordinea de rezolvare a metodelor (MRO) nu este conformă cu CPython

Cauză: Ordinea de rezolvare a metodelor este depth-first și neexhaustivă

Soluție alternativă: Evitați ierarhii de clase complexe cu moștenire multiplă și suprascrierea complexă a metodelor. Rețineți că multe limbaje nu suportă deloc moștenirea multiplă.

Cod exemplu:

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)

Modificarea numelor membrilor privați ai claselor (name mangling) nu este implementată

Cauză: Compilatorul MicroPython nu implementează name mangling pentru membrii privați ai claselor.

Soluție alternativă: Evitați utilizarea sau coliziunea cu numele globale adăugând manual un prefix unic la numele membrului privat al clasei.

Cod exemplu:

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.

La moștenirea tipurilor native, apelarea unei metode în __init__(self, ...) înainte de super().__init__() ridică un AttributeError (sau provoacă segfault dacă MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG nu este activat).

Cauză: MicroPython nu are metode separate __new__ și __init__ în tipurile native.

Soluție alternativă: Apelați mai întâi super().__init__().

Cod exemplu:

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

La moștenirea din mai multe clase, super() apelează doar o singură clasă

Cauză: Consultați Ordinea de rezolvare a metodelor (MRO) nu este conformă cu CPython

Soluție alternativă: Consultați Ordinea de rezolvare a metodelor (MRO) nu este conformă cu CPython

Cod exemplu:

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__

Apelarea proprietății getter super() într-o subclasă va returna un obiect property, nu valoarea

Cod exemplu:

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.

Cod exemplu:

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

Funcții

Mesajele de eroare pentru metode pot afișa un număr neașteptat de argumente

Cauză: MicroPython numără „self” ca argument.

Soluție alternativă: Interpretați mesajele de eroare ținând cont de informațiile de mai sus.

Cod exemplu:

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

Obiectele funcție nu au atributul __module__

Cauză: MicroPython este optimizat pentru dimensiunea redusă a codului și utilizarea RAM.

Soluție alternativă: Folosiți sys.modules[function.__globals__['__name__']] pentru modulele non-built-in.

Cod exemplu:

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

Atributele definite de utilizator pentru funcții nu sunt suportate

Cauză: MicroPython este optimizat în mare măsură pentru utilizarea memoriei.

Soluție alternativă: Folosiți un dicționar extern, de ex. FUNC_X[f] = 0.

Cod exemplu:

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

Managerul de context __exit__() nu este apelat într-un generator care nu rulează până la finalizare

Cod exemplu:

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

Runtime

Variabilele locale nu sunt incluse în rezultatul locals()

Cauză: MicroPython nu menține un mediu local simbolic, este optimizat la un array de sloturi. Prin urmare, variabilele locale nu pot fi accesate după nume.

Cod exemplu:

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


test()

CPython output:

MicroPython output:

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

Codul care rulează în funcția eval() nu are acces la variabilele locale

Cauză: MicroPython nu menține un mediu local simbolic, este optimizat la un array de sloturi. Prin urmare, variabilele locale nu pot fi accesate după nume. Efectiv, eval(expr) în MicroPython este echivalent cu eval(expr, globals(), globals()).

Cod exemplu:

val = 1


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


test()

CPython output:

MicroPython output:

2
2
2
1

f-strings

f-strings nu suportă concatenarea cu literale adiacente dacă literalele adiacente conțin acolade

Cauză: MicroPython este optimizat pentru spațiul de cod.

Soluție alternativă: Folosiți operatorul + între șiruri literale atunci când nu sunt ambele f-strings

Cod exemplu:

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 nu pot suporta expresii care necesită analiză pentru a rezolva acolade și paranteze imbricate neechilibrate

Cauză: MicroPython este optimizat pentru spațiul de cod.

Soluție alternativă: Folosiți întotdeauna acolade și paranteze echilibrate în expresiile din interiorul f-strings

Cod exemplu:

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 nu suportă conversiile !a

Cauză: MicroPython nu implementează ascii()

Soluție alternativă: Niciuna

Cod exemplu:

f"{'unicode text'!a}"

CPython output:

MicroPython output:

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

import

Atributul __path__ al unui pachet are un tip diferit (un șir unic în loc de o listă de șiruri) în MicroPython

Cauză: MicroPython nu suportă pachete de spații de nume distribuite pe sistemul de fișiere. În plus, sistemul de import din MicroPython este optimizat pentru utilizare minimă a memoriei.

Soluție alternativă: Detaliile gestionării importurilor sunt în mod inerent dependente de implementare. Nu vă bazați pe astfel de detalii în aplicațiile portabile.

Cod exemplu:

import modules

print(modules.__path__)

CPython output:

MicroPython output:

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

MicroPython nu suportă pachete de spații de nume distribuite pe sistemul de fișiere.

Cauză: Sistemul de import din MicroPython este optimizat în mare măsură pentru simplitate, utilizare minimă a memoriei și overhead minim de căutare în sistemul de fișiere.

Soluție alternativă: Nu instalați module aparținând aceluiași pachet de spații de nume în directoare diferite. Pentru MicroPython, se recomandă cel mult 3 componente în căile de căutare a modulelor: pentru aplicația curentă, per utilizator (cu scriere), la nivel de sistem (fără scriere).

Cod exemplu:

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'