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__)
基本上,我有一个列表列表,如下所示:
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__)