Использование отражения, чтобы заглянуть в модуль и его классы - PullRequest
3 голосов
/ 05 февраля 2012

У меня есть проблема, которую немного сложно объяснить.У меня есть модуль, который состоит из более чем одного класса: someModule.py

#imports over here
class Default(Base):
 def __init__(self):
   a = Rectangle() #all these guys derive from Shape
   b = Circle()
   c = Sphere()

class Foo:
 #members over here

#other classes/functions/whatever we can define here, except the boiler plate code to check __main__

Что я хочу сделать, это создать объект класса, который наследуется от определенного базового класса (например, Base) при запускевремя и манипулировать теми членами данных, которые являются производными от другого конкретного базового класса (например, Shape).То есть я хочу написать такой скрипт, который принимает имя модуля и выполняет вышеуказанную задачу.Любые идеи, как я могу сделать это с помощью инспекции или что-то еще?Я посмотрел на осмотреть, но не совсем нашел методы, которые должны сделать работу.Я могу что-то упустить.

Ответы [ 2 ]

1 голос
/ 05 февраля 2012

Нет способа узнать, что находится внутри __init__ до создания экземпляра.

Вы можете проверить их только после, и один из способов сделать это - vars():

defy = Default()
for name,value in vars(defy).items():
    if isinstance(value, Shape):
        # manipulate

Для выполнения вышеприведенного на всех классах в someModule.py, которые также являются подклассами Base:

import someModule

instances = []
for cls_name,cls in vars(someModule):
    if issubclass(cls, Base):
        obj = cls()
        for name,value in vars(cls).items():
            if isinstance(value, Shape):
                # manipulate
        instances.append(obj)

Вместо этого, если вы хотите манипулировать каким Shape Подкласс будет создан, вы должны будете сделать их атрибутами класса, например:

class Default(Base):
    default_shapes = [Rectangle, Circle, Sphere]
    def __init__(self):
        self.shapes = [shape() for shape in self.__class__.default_shapes]
0 голосов
/ 05 февраля 2012

Вот один из способов: убедитесь, что ваши базовые классы (например, Base, Shape) классы нового стиля (они наследуются от object). Таким образом, вы можете использовать встроенную функцию __subclasses__(), чтобы получить список всех производных классов. Затем вы можете просто создать объект и просмотреть поля, сравнивая их с интересующими вас классами.

baseDerived = Base.__subclasses__()
shapeDerived = Shape.__subclasses__()

# Iterate through derived classes
for derivedClass in baseDerived:
    derivedObject = derivedClass()

    # Iterate through data attributes
    for attr, dataMember in derivedObject.__dict__.iteritems():
        if dataMember.__class__ in shapeDerived:
            # Do stuff with the data member here
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...