اللغة الأساسية

Generated Thu 18 Jun 2026 05:00:56 UTC

الفئات

الأسلوب الخاص __del__ غير مُنفَّذ للفئات المعرَّفة من قِبَل المستخدم

مثال على الكود:

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

مثال على الكود:

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.

مثال على الكود:

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.

مثال على الكود:

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.

مثال على الكود:

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

ترتيب دقة الأساليب (MRO) غير متوافق مع CPython

السبب: ترتيب دقة الأساليب بالعمق أولاً وغير استنزافي

الحل البديل: تجنب التسلسل الهرمي المعقد للفئات مع الوراثة المتعددة وتجاوزات الأساليب المعقدة. ضع في اعتبارك أن كثيراً من اللغات لا تدعم الوراثة المتعددة على الإطلاق.

مثال على الكود:

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)

تشويه أسماء الأعضاء الخاصة للفئة غير مُنفَّذ

السبب: مترجم MicroPython لا يُنفِّذ تشويه الأسماء لأعضاء الفئة الخاصة.

الحل البديل: تجنب استخدام أسماء عالمية أو التصادم معها، وذلك بإضافة بادئة فريدة يدوياً إلى اسم العضو الخاص في الفئة.

مثال على الكود:

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.

عند وراثة الأنواع الأصلية، يؤدي استدعاء أسلوب في __init__(self, ...) قبل super().__init__() إلى رفع AttributeError (أو segfault إذا لم يكن MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG مُفعَّلاً).

السبب: MicroPython لا يحتوي على أساليب __new__ و``__init__`` منفصلة في الأنواع الأصلية.

الحل البديل: استدعِ super().__init__() أولاً.

مثال على الكود:

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

عند الوراثة من فئات متعددة، يستدعي super() فئة واحدة فقط

السبب: انظر ترتيب دقة الأساليب (MRO) غير متوافق مع CPython

الحل البديل: انظر ترتيب دقة الأساليب (MRO) غير متوافق مع CPython

مثال على الكود:

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__

استدعاء خاصية getter للـ super() في الفئة الفرعية سيُعيد كائن property وليس القيمة

مثال على الكود:

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.

مثال على الكود:

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

الدوال

قد تعرض رسائل الخطأ للأساليب أعداد وسيطات غير متوقعة

السبب: MicroPython يحسب "self" كوسيطة.

الحل البديل: فسِّر رسائل الخطأ مع مراعاة المعلومات أعلاه.

مثال على الكود:

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

كائنات الدوال لا تحتوي على السمة __module__

السبب: تم تحسين MicroPython لتقليل حجم الكود واستخدام RAM.

الحل البديل: استخدم sys.modules[function.__globals__['__name__']] للوحدات غير المدمجة.

مثال على الكود:

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

السمات المعرَّفة من قِبَل المستخدم للدوال غير مدعومة

السبب: تم تحسين MicroPython بشكل كبير لاستخدام الذاكرة.

الحل البديل: استخدم قاموساً خارجياً، مثلاً FUNC_X[f] = 0.

مثال على الكود:

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'

المولّد

لا يُستدعى __exit__() لمدير السياق في مولِّد لا يُكمل تنفيذه

مثال على الكود:

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

وقت التشغيل

المتغيرات المحلية غير مُضمَّنة في نتيجة locals()

السبب: MicroPython لا يحتفظ بالبيئة المحلية الرمزية، إذ تم تحسينه إلى مصفوفة من الفتحات. وبالتالي، لا يمكن الوصول إلى المتغيرات المحلية بالاسم.

مثال على الكود:

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


test()

CPython output:

MicroPython output:

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

الكود الذي يعمل داخل دالة eval() لا يمكنه الوصول إلى المتغيرات المحلية

السبب: MicroPython لا يحتفظ بالبيئة المحلية الرمزية، إذ تم تحسينه إلى مصفوفة من الفتحات. وبالتالي، لا يمكن الوصول إلى المتغيرات المحلية بالاسم. فعلياً، eval(expr) في MicroPython يعادل eval(expr, globals(), globals()).

مثال على الكود:

val = 1


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


test()

CPython output:

MicroPython output:

2
2
2
1

f-strings

f-strings لا تدعم الدمج مع الحروف الحرفية المجاورة إذا احتوت تلك الحروف على أقواس معقوصة

السبب: تم تحسين MicroPython لتوفير مساحة الكود.

الحل البديل: استخدم عامل + بين السلاسل الحرفية عندما لا تكون كلتاهما f-strings

مثال على الكود:

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 لا يمكنها دعم التعابير التي تتطلب تحليلاً لحل الأقواس المتداخلة غير المتوازنة

السبب: تم تحسين MicroPython لتوفير مساحة الكود.

الحل البديل: استخدم دائماً أقواساً متوازنة في التعابير داخل f-strings

مثال على الكود:

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 لا تدعم تحويلات !a

السبب: MicroPython لا يُنفِّذ ascii()

الحل البديل: لا يوجد

مثال على الكود:

f"{'unicode text'!a}"

CPython output:

MicroPython output:

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

import

سمة __path__ للحزمة لها نوع مختلف (سلسلة واحدة بدلاً من قائمة من السلاسل) في MicroPython

السبب: MicroPython لا يدعم حزم النطاق المقسَّمة عبر نظام الملفات. علاوة على ذلك، نظام الاستيراد في MicroPython مُحسَّن بشكل كبير لتقليل استخدام الذاكرة.

الحل البديل: تفاصيل معالجة الاستيراد تعتمد بطبيعتها على التنفيذ. لا تعتمد على مثل هذه التفاصيل في التطبيقات المحمولة.

مثال على الكود:

import modules

print(modules.__path__)

CPython output:

MicroPython output:

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

MicroPython لا يدعم حزم النطاق المقسَّمة عبر نظام الملفات.

السبب: نظام الاستيراد في MicroPython مُحسَّن بشكل كبير للبساطة وتقليل استخدام الذاكرة وتقليل الحمل الزائد للبحث في نظام الملفات.

الحل البديل: لا تثبِّت الوحدات التابعة لنفس حزمة النطاق في أدلة مختلفة. في MicroPython، يُوصى باستخدام مسارات بحث عن الوحدات بحد أقصى 3 مكونات: للتطبيق الحالي، ولكل مستخدم (قابل للكتابة)، وعلى مستوى النظام (غير قابل للكتابة).

مثال على الكود:

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'