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_container
untuk 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_class
yang merupakan referensi ke variabel self
fungsi ini, yang _subclass_container
dapat diakses sub-kelas (hindari konflik nama dengan self
variabel lain di subkelas).
Kembalikan sub-kelas / sub-kelas sebagai kamus / daftar sehingga kode yang memanggil _subclass_container
fungsi 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_container
ke dalam variabel subclasses
.
Tetapkan sub-kelas yang disimpan dalam subclasses
variabel 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_func
telah dihapus) dan satu-satunya solusi tanpa menulis ulang kode di kelas a.x1
adalah dengan mendefinisikan kembali sub-kelas x1
dengan kode yang diperbarui untuk semua kelas yang diturunkan dari kelas "a" yang jelas akan sulit dan tidak bernilai. Itu.