Решение
Это работает:
class Action:
pass
class Move(Action):
pass
class Look(Action):
pass
actions = []
global_objs = list(globals().items())
for name, obj in global_objs:
if obj is not Action and isinstance(obj, type) and issubclass(obj, Action):
actions.append(obj())
print(actions)
печатает:
[<__main__.Move object at 0x101916ba8>, <__main__.Look object at 0x101916be0>]
Шаги
Сначала мы получаем все имена объекта в текущем модуле:
global_objs = list(globals().items())
Нам нужно преобразовать в список, потому что в Python 3 items()
возвращает объект dictview, который отражает изменения в нижележащем словаре. Поскольку мы работаем в одном модуле, определение новых объектов изменит этот словарь. Преобразование в список решает эту проблему.
Далее проходим по всем объектам. Чтобы стать подклассом Action
, им необходимо выполнить три условия:
obj is not Action
- Поскольку Action
является подклассом самого себя, нам нужно отфильтровать его.
isinstance(obj, type)
- Объект должен быть классом. В противном случае проверка в соответствии с 3. будет невозможна.
issubclass(obj, Action)
- Наконец, мы можем провести тест нашего подкласса.
Теперь мы можем создать экземпляры всех отфильтрованных классов и добавить их в наш список:
actions.append(obj())
Укороченная версия
Если вы уверены, что все классы определены в одном модуле или даже хотите, чтобы все подклассы были распределены по нескольким модулям, это будет намного короче:
>>> actions = [obj() for obj in Action.__subclasses__()]
>>> actions
[<__main__.Move at 0x10fc14fd0>, <__main__.Look at 0x10fc14668>]
person
Mike Müller
schedule
01.01.2016