Bahasa inti¶
Generated Thu 18 Jun 2026 19:58:13 UTC
Kelas¶
Metode khusus __del__ tidak diimplementasikan untuk kelas yang ditentukan pengguna¶
Contoh kode:
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__()
Contoh kode:
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.
Contoh kode:
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.
Contoh kode:
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.
Contoh kode:
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__'
|
Method Resolution Order (MRO) tidak sesuai dengan CPython¶
Penyebab: Urutan resolusi metode depth-first yang tidak exhaustive
Solusi: Hindari hierarki kelas yang kompleks dengan pewarisan berganda dan penggantian metode yang kompleks. Ingat bahwa banyak bahasa tidak mendukung pewarisan berganda sama sekali.
Contoh kode:
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)
|
Mangling nama anggota kelas privat tidak diimplementasikan¶
Penyebab: Kompiler MicroPython tidak mengimplementasikan mangling nama untuk anggota kelas privat.
Solusi: Hindari penggunaan atau tabrakan dengan nama global, dengan menambahkan awalan unik pada nama anggota kelas privat secara manual.
Contoh kode:
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.
|
Ketika mewarisi tipe asli, memanggil metode dalam __init__(self, ...) sebelum super().__init__() menimbulkan AttributeError (atau segfault jika MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG tidak diaktifkan).¶
Penyebab: MicroPython tidak memiliki metode __new__ dan __init__ yang terpisah dalam tipe asli.
Solusi: Panggil super().__init__() terlebih dahulu.
Contoh kode:
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
|
Saat mewarisi dari beberapa kelas, super() hanya memanggil satu kelas¶
Penyebab: Lihat Method Resolution Order (MRO) tidak sesuai dengan CPython
Solusi: Lihat Method Resolution Order (MRO) tidak sesuai dengan CPython
Contoh kode:
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__
|
Memanggil properti getter super() di subkelas akan mengembalikan objek property, bukan nilainya¶
Contoh kode:
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.
Contoh kode:
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
|
Fungsi¶
Pesan kesalahan untuk metode mungkin menampilkan jumlah argumen yang tidak terduga¶
Penyebab: MicroPython menghitung "self" sebagai argumen.
Solusi: Interpretasikan pesan kesalahan dengan informasi di atas sebagai pertimbangan.
Contoh kode:
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
|
Objek fungsi tidak memiliki atribut __module__¶
Penyebab: MicroPython dioptimalkan untuk ukuran kode yang lebih kecil dan penggunaan RAM.
Solusi: Gunakan sys.modules[function.__globals__['__name__']] untuk modul non-bawaan.
Contoh kode:
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__'
|
Atribut yang ditentukan pengguna untuk fungsi tidak didukung¶
Penyebab: MicroPython sangat dioptimalkan untuk penggunaan memori.
Solusi: Gunakan dictionary eksternal, misalnya FUNC_X[f] = 0.
Contoh kode:
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¶
Context manager __exit__() tidak dipanggil dalam generator yang tidak berjalan hingga selesai¶
Contoh kode:
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¶
Variabel lokal tidak disertakan dalam hasil locals()¶
Penyebab: MicroPython tidak mempertahankan lingkungan lokal simbolis, ia dioptimalkan menjadi array slot. Oleh karena itu, variabel lokal tidak dapat diakses berdasarkan nama.
Contoh kode:
def test():
val = 2
print(locals())
test()
CPython output: |
MicroPython output: |
{'val': 2}
|
{'test': <function test at 0x7f186c605260>, '__name__': '__main__', '__file__': '<stdin>'}
|
Kode yang berjalan dalam fungsi eval() tidak memiliki akses ke variabel lokal¶
Penyebab: MicroPython tidak mempertahankan lingkungan lokal simbolis, ia dioptimalkan menjadi array slot. Oleh karena itu, variabel lokal tidak dapat diakses berdasarkan nama. Secara efektif, eval(expr) di MicroPython setara dengan eval(expr, globals(), globals()).
Contoh kode:
val = 1
def test():
val = 2
print(val)
eval("print(val)")
test()
CPython output: |
MicroPython output: |
2
2
|
2
1
|
f-strings¶
f-string tidak mendukung penggabungan dengan literal yang berdekatan jika literal tersebut mengandung kurung kurawal¶
Penyebab: MicroPython dioptimalkan untuk ruang kode.
Solusi: Gunakan operator + antara string literal ketika keduanya bukan f-string
Contoh kode:
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-string tidak dapat mendukung ekspresi yang memerlukan penguraian untuk menyelesaikan kurung kurawal dan tanda kurung bersarang yang tidak seimbang¶
Penyebab: MicroPython dioptimalkan untuk ruang kode.
Solusi: Selalu gunakan kurung kurawal dan tanda kurung yang seimbang dalam ekspresi di dalam f-string
Contoh kode:
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-string tidak mendukung konversi !a¶
Penyebab: MicroPython tidak mengimplementasikan ascii()
Solusi: Tidak ada
Contoh kode:
f"{'unicode text'!a}"
CPython output: |
MicroPython output: |
Traceback (most recent call last):
File "<stdin>", line 8
SyntaxError: invalid syntax
|
import¶
Atribut __path__ dari sebuah paket memiliki tipe yang berbeda (string tunggal alih-alih list string) di MicroPython¶
Penyebab: MicroPython tidak mendukung paket namespace yang tersebar di seluruh filesystem. Selain itu, sistem import MicroPython sangat dioptimalkan untuk penggunaan memori yang minimal.
Solusi: Detail penanganan import secara inheren bergantung pada implementasi. Jangan mengandalkan detail tersebut dalam aplikasi yang portabel.
Contoh kode:
import modules
print(modules.__path__)
CPython output: |
MicroPython output: |
['/home/runner/work/openmv-doc/openmv-doc/micropython/tests/cpydiff/modules']
|
../tests/cpydiff/modules
|
MicroPython tidak mendukung paket namespace yang tersebar di seluruh filesystem.¶
Penyebab: Sistem import MicroPython sangat dioptimalkan untuk kesederhanaan, penggunaan memori minimal, dan overhead pencarian filesystem yang minimal.
Solusi: Jangan menginstal modul yang termasuk dalam paket namespace yang sama di direktori yang berbeda. Untuk MicroPython, disarankan untuk memiliki maksimal 3 komponen jalur pencarian modul: untuk aplikasi Anda saat ini, per-pengguna (dapat ditulis), seluruh sistem (tidak dapat ditulis).
Contoh kode:
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'
|