Saya telah membuat beberapa kode Python untuk menggunakan kelas luar dari kelas dalam , berdasarkan ide bagus dari jawaban lain untuk pertanyaan ini. Menurut saya ini singkat, sederhana dan mudah dimengerti.
class higher_level__unknown_irrelevant_name__class:
def __init__(self, ...args...):
...other code...
# Important lines to access sub-classes.
subclasses = self._subclass_container()
self.some_subclass = subclasses["some_subclass"]
del subclasses # Free up variable for other use.
def sub_function(self, ...args...):
...other code...
def _subclass_container(self):
_parent_class = self # Create access to parent class.
class some_subclass:
def __init__(self):
self._parent_class = _parent_class # Easy access from self.
# Optional line, clears variable space, but SHOULD NOT BE USED
# IF THERE ARE MULTIPLE SUBCLASSES as would stop their parent access.
# del _parent_class
class subclass_2:
def __init__(self):
self._parent_class = _parent_class
# Return reference(s) to the subclass(es).
return {"some_subclass": some_subclass, "subclass_2": subclass_2}
Kode utama, "produksi siap" (tanpa komentar, dll.). Ingatlah untuk mengganti semua nilai dalam tanda kurung siku (misalnya <x>) dengan nilai yang diinginkan.
class <higher_level_class>:
def __init__(self):
subclasses = self._subclass_container()
self.<sub_class> = subclasses[<sub_class, type string>]
del subclasses
def _subclass_container(self):
_parent_class = self
class <sub_class>:
def __init__(self):
self._parent_class = _parent_class
return {<sub_class, type string>: <sub_class>}
Penjelasan cara kerja metode ini (langkah-langkah dasar):
Buat fungsi bernama _subclass_containeruntuk bertindak sebagai pembungkus untuk mengakses variabel self, referensi ke kelas tingkat yang lebih tinggi (dari kode yang berjalan di dalam fungsi).
Buat variabel bernama _parent_classyang merupakan referensi ke variabel selffungsi ini, yang _subclass_containerdapat diakses sub-kelas (hindari konflik nama dengan selfvariabel lain di subkelas).
Kembalikan sub-kelas / sub-kelas sebagai kamus / daftar sehingga kode yang memanggil _subclass_containerfungsi dapat mengakses sub-kelas di dalamnya.
Dalam __init__fungsi di dalam kelas tingkat yang lebih tinggi (atau di mana pun dibutuhkan), menerima sub-kelas yang dikembalikan dari fungsi _subclass_containerke dalam variabel subclasses.
Tetapkan sub-kelas yang disimpan dalam subclassesvariabel ke atribut kelas tingkat yang lebih tinggi.
Beberapa tip untuk membuat skenario lebih mudah:
Membuat kode untuk menetapkan sub kelas ke kelas tingkat yang lebih tinggi lebih mudah untuk disalin dan digunakan di kelas yang berasal dari kelas tingkat yang lebih tinggi yang __init__ fungsinya berubah:
Sisipkan sebelum baris 12 di kode utama:
def _subclass_init(self):
Kemudian masukkan ke dalam fungsi ini baris 5-6 (dari kode utama) dan ganti baris 4-7 dengan kode berikut:
self._subclass_init(self)
Membuat subclass menetapkan ke kelas tingkat yang lebih tinggi mungkin ketika ada banyak / jumlah subclass yang tidak diketahui.
Ganti baris 6 dengan kode berikut:
for subclass_name in list(subclasses.keys()):
setattr(self, subclass_name, subclasses[subclass_name])
Contoh skenario di mana solusi ini akan berguna dan di mana nama kelas tingkat yang lebih tinggi seharusnya tidak mungkin didapat:
Sebuah kelas, bernama "a" ( class a:) dibuat. Ini memiliki subclass yang perlu mengaksesnya (induk). Satu subclass disebut "x1". Di subclass ini, kode a.run_func()dijalankan.
Kemudian kelas lain, bernama "b" dibuat, diturunkan dari kelas "a" ( class b(a):). Setelah itu, beberapa kode dijalankan b.x1()(memanggil subfungsi "x1" dari b, sub-kelas turunan). Fungsi ini berjalan a.run_func(), memanggil fungsi "run_func" dari kelas "a", bukan fungsi "run_func" dari induknya, "b" (sebagaimana mestinya), karena fungsi yang didefinisikan di kelas "a" diatur untuk merujuk ke fungsi kelas "a", karena itu adalah induknya.
Hal ini akan menyebabkan masalah (misalnya jika fungsi a.run_functelah dihapus) dan satu-satunya solusi tanpa menulis ulang kode di kelas a.x1adalah dengan mendefinisikan kembali sub-kelas x1dengan kode yang diperbarui untuk semua kelas yang diturunkan dari kelas "a" yang jelas akan sulit dan tidak bernilai. Itu.