Python:如何将列表变量的名称分配给 class

Python: how to assign a name of a list variable to a class

基本上,我有一个列表列表,如下所示:

lst = [['B', 'A'], ['C', 'B'], ['D', 'B'], ['E','C D'] ......]

其中 t[0] 应该是 t[1] 的子类(从中继承)。

我需要编写一个脚本来创建名称与 lst 匹配的空 类,然后检查何时 t[i-1]t[i] 的子类:

if issubclass(B, A)== True:
   print('Yes')
   

到目前为止,我了解如何开始和完成脚本,但我完全不知道如何从列表中指定名称以便可以使用 issubclass。 也许还有其他方法可以创建 类 并追踪它们的继承?

我今天才开始学习 类 和 OOP,所以我很可能在处理这个问题时错过了一些重要的东西。

我们通常定义 类 的方式自然是使用 class 关键字。

class B(A):
    some_variable = 100

实际上,我们正在 构建 Python 运行时中的新类型。而且,事实上,类型在 Python 中有自己的构造函数;它叫做type,我们可以直接调用它。上面的声明大致相当于

B = type('B', ('A',), { 'some_variable': 100 })

现在类型名称是字符串。我们还需要一块拼图。我们想使用字符串将其分配给名称 B,这样我们就可以使用事先不知道的名称来执行此操作。假设您想在模块范围内执行此操作,我们可以使用 globals,其中 returns 当前模块顶级变量的字典,我们可以自由修改以添加更多变量。所以我们可以做

globals()['B'] = type('B', ('A',), { 'some_variable': 100 })

现在,让我们将这些部分放在一起并编写一个使用您建议的 lst 列表的脚本。

lst = [['B', 'A'], ['C', 'B'], ['D', 'B'], ['E','C D']]

# Iterate over the list.
for class_name, superclass_names in lst:
    # Here, we're going to lookup all of the superclass names in the
    # current global scope. It's a little more complicated than that,
    # since we also want to *create* any names that don't exist (like
    # 'A' in your example) when we find them.
    superclasses = []
    for superclass_name in superclass_names.split(' '):
        # If the name doesn't exist, create it and assume its
        # supertype is object, the root of Python's type hierarchy.
        if superclass_name not in globals():
            globals()[superclass_name] = type(superclass_name, (object,), {})
        # Get the class, whether it's the one we just made or one that
        # already exists.
        superclasses.append(globals()[superclass_name])
    # Now we construct the new class. The first argument to type() is
    # the class name, the second is all of the superclasses (it must
    # be a tuple, not a list, according to the documentation, so we
    # convert it), and finally the contents. Since you just want the
    # classes themselves, I'll assume the contents are meant to be
    # empty. You can easily change that as needed.
    globals()[class_name] = type(class_name, tuple(superclasses), {})

# Now let's see that everything is defined correctly. __mro__ is a
# complicated concept, but the basic idea is that it should give us E,
# followed by all of its subclasses in a reasonable order (for some
# definition of reasonable).
print(E.__mro__)

Try it online!