根据另一个 answer 的一个好主意,我已经创建了一些 Python 代码来使用其 内部类 中的 外部类。我认为它简短、简单且易于理解。
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}
主要代码,“生产就绪”(没有 cmets 等)。请记住将尖括号中的所有值(例如<x>)替换为所需的值。
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>}
说明此方法的工作原理(基本步骤):
-
创建一个名为_subclass_container 的函数作为包装器来访问变量self,这是对更高级别类的引用(来自函数内部运行的代码)。
创建一个名为_parent_class的变量,这是对该函数的变量self的引用,_subclass_container的子类可以访问(避免与子类中的其他self变量发生名称冲突)。
将子类/子类作为字典/列表返回,以便调用_subclass_container 函数的代码可以访问其中的子类。
在更高级别类中的__init__ 函数中(或其他任何需要的地方),将函数_subclass_container 返回的子类接收到变量subclasses 中。
将存储在subclasses 变量中的子类分配给更高级别类的属性。
让场景更简单的一些技巧:
使将子类分配给更高级别类的代码更易于复制并用于从更高级别类派生的类中使用 __init__ 功能已更改:
在主代码的第 12 行之前插入:
def _subclass_init(self):
然后将第 5-6 行(主代码)插入到此函数中,并将第 4-7 行替换为以下代码:
self._subclass_init(self)
当有许多/未知数量的子类时,可以将子类分配给更高级别的类。
将第 6 行替换为以下代码:
for subclass_name in list(subclasses.keys()):
setattr(self, subclass_name, subclasses[subclass_name])
此解决方案在哪里有用以及在哪里应该不可能获得更高级别的类名的示例场景:
创建了一个名为“a”(class a:) 的类。它有需要访问它的子类(父类)。一个子类称为“x1”。在这个子类中,运行代码a.run_func()。
然后创建另一个名为“b”的类,派生自“a”类 (class b(a):)。之后,一些代码运行b.x1()(调用b的子函数“x1”,一个派生的子类)。这个函数运行a.run_func(),调用类“a”的函数“run_func”,不是它的父类“b”的函数“run_func”(应该如此),因为这个函数是在“a”类中定义的函数被设置为引用“a”类的函数,因为那是它的父类。
这会导致问题(例如,如果函数 a.run_func 已被删除),唯一的解决方案是不重写类 a.x1 中的代码,将重新定义子类 x1,并为所有派生的类更新代码“a”类显然是困难的,不值得。