Tôi đã tạo ra một số mã Python để sử dụng một lớp bên ngoài từ lớp bên trong của nó, dựa trên một ý tưởng tốt từ một câu trả lời khác cho câu hỏi này. Tôi nghĩ nó ngắn, đơn giản và dễ hiểu.
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}
Mã chính, "Sản xuất sẵn sàng" [không có bình luận, v.v.]. Hãy nhớ thay thế tất cả mỗi giá trị trong khung góc [ví dụ: ] bằng giá trị mong muốn.
class :
def __init__[self]:
subclasses = self._subclass_container[]
self. = subclasses[]
del subclasses
def _subclass_container[self]:
_parent_class = self
class :
def __init__[self]:
self._parent_class = _parent_class
return {: }
Giải thích về cách thức hoạt động của phương pháp này [các bước cơ bản]:
Tạo một hàm có tên
_subclass_container
để hoạt động như một trình bao bọc để truy cập biếnself
, tham chiếu đến lớp cấp cao hơn [từ mã chạy bên trong hàm].Tạo một biến có tên
_parent_class
là một tham chiếu đến biếnself
của hàm này, rằng các lớp con của_subclass_container
có thể truy cập [tránh tên xung đột với các biến ____77 khác trong các lớp con].Trả về các lớp phụ/lớp con dưới dạng từ điển/danh sách để mã gọi hàm
_subclass_container
có thể truy cập các lớp con bên trong.
Trong hàm
3 bên trong lớp cấp cao hơn [hoặc bất cứ nơi nào khác cần], hãy nhận các lớp con được trả về từ hàmclass : def __init__[self]: subclasses = self._subclass_container[] self. = subclasses[] del subclasses def _subclass_container[self]: _parent_class = self class : def __init__[self]: self._parent_class = _parent_class return {: }
_subclass_container
vào biến
5.class : def __init__[self]: subclasses = self._subclass_container[] self. = subclasses[] del subclasses def _subclass_container[self]: _parent_class = self class : def __init__[self]: self._parent_class = _parent_class return {: }
Chỉ định các lớp phụ được lưu trữ trong biến
5 cho các thuộc tính của lớp cấp cao hơn.class : def __init__[self]: subclasses = self._subclass_container[] self. = subclasses[] del subclasses def _subclass_container[self]: _parent_class = self class : def __init__[self]: self._parent_class = _parent_class return {: }
Một vài mẹo để làm cho kịch bản dễ dàng hơn:
Làm cho mã để gán các lớp con cho lớp cấp cao hơn dễ dàng sao chép và được sử dụng trong các lớp có nguồn gốc từ lớp cấp cao hơn có chức năng
3 của chúng đã thay đổi: class :
def __init__[self]:
subclasses = self._subclass_container[]
self. = subclasses[]
del subclasses
def _subclass_container[self]:
_parent_class = self
class :
def __init__[self]:
self._parent_class = _parent_class
return {: }
class :
def __init__[self]:
subclasses = self._subclass_container[]
self. = subclasses[]
del subclasses
def _subclass_container[self]:
_parent_class = self
class :
def __init__[self]:
self._parent_class = _parent_class
return {: }
3 function changed:Chèn trước dòng 12 trong mã chính:
def _subclass_init[self]:
Sau đó chèn vào các dòng chức năng này 5-6 [của mã chính] và thay thế các dòng 4-7 bằng mã sau:
self._subclass_init[self]
Làm cho lớp con gán cho lớp cấp cao hơn có thể khi có nhiều/số lượng con chưa biết.
Thay thế dòng 6 bằng mã sau:
for subclass_name in list[subclasses.keys[]]:
setattr[self, subclass_name, subclasses[subclass_name]]
Kịch bản ví dụ về nơi giải pháp này sẽ hữu ích và không thể có được tên lớp cấp cao hơn:
Một lớp, được đặt tên là "A" [
class :
def __init__[self]:
subclasses = self._subclass_container[]
self. = subclasses[]
del subclasses
def _subclass_container[self]:
_parent_class = self
class :
def __init__[self]:
self._parent_class = _parent_class
return {: }
8] được tạo. Nó có các lớp con cần truy cập nó [cha mẹ]. Một lớp con được gọi là "x1". Trong lớp con này, mã class :
def __init__[self]:
subclasses = self._subclass_container[]
self. = subclasses[]
del subclasses
def _subclass_container[self]:
_parent_class = self
class :
def __init__[self]:
self._parent_class = _parent_class
return {: }
9 được chạy.Sau đó, một lớp khác, được đặt tên là "B" được tạo ra, xuất phát từ lớp "A" [
def _subclass_init[self]:
0]. Sau đó, một số mã chạy def _subclass_init[self]:
1 [gọi hàm phụ là "x1" của B, một lớp phụ có nguồn gốc]. Hàm này chạy class :
def __init__[self]:
subclasses = self._subclass_container[]
self. = subclasses[]
del subclasses
def _subclass_container[self]:
_parent_class = self
class :
def __init__[self]:
self._parent_class = _parent_class
return {: }
9, gọi hàm là "Run_func" của lớp "A", không phải hàm "Run_func" của cha mẹ của nó, "B" [như bình thường], vì hàm được xác định trong lớp "A" được đặt thành Tham khảo chức năng của lớp "A", vì đó là cha mẹ của nó.derived from class "a" [def _subclass_init[self]:
0]. After that, some
code runs def _subclass_init[self]:
1 [calling the sub function "x1" of b, a derived sub-class]. This function runs class :
def __init__[self]:
subclasses = self._subclass_container[]
self. = subclasses[]
del subclasses
def _subclass_container[self]:
_parent_class = self
class :
def __init__[self]:
self._parent_class = _parent_class
return {: }
9, calling the function "run_func" of class "a", not the function "run_func" of its parent, "b" [as it should], because the function which was defined in class "a" is set to refer to the function of class "a", as that was its parent.Điều này sẽ gây ra các vấn đề [ví dụ: nếu hàm
def _subclass_init[self]:
3 đã bị xóa] và giải pháp duy nhất mà không viết lại mã trong lớp def _subclass_init[self]:
4 sẽ là xác định lại lớp phụ Và không đáng giá.