اللغة الأساسية¶
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'
|