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

问题描述

基本上,我有一个看起来像这样的列表:

lst = [['B','A'],['C','B'],['D',['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,它返回当前模块顶级变量的字典,我们可以自由修改以添加更多变量。所以我们可以做

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

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

lst = [['B','A'],['C','B'],['D',['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!