Способ Pythonic присвоить экземпляр подкласса к переменной, когда определенная строка представлена конструктору родительского класса

Я хочу смочь создать экземпляр родительского класса X со строкой "Q" как дополнительный аргумент.
Эта строка должна быть именем, являющимся идентификатором для подкласса Q родительского класса X.
Я хочу, чтобы экземпляр родительского класса стал (или был заменен) экземпляр подкласса.

Я знаю, что это - вероятно, классическая проблема (ошибка?). После некоторого поиска я не нашел подходящее решение все же.
Я предложил следующее решение сам;
Я добавил словарь возможных идентификаторов как ключи для их экземпляров базового класса к init-методу родительского класса.
Затем присвоенный атрибут класса соответствующего подкласса к текущему атрибуту класса экземпляров.
Я потребовал, чтобы аргументом init-метода не было значение по умолчанию для предотвращения бесконечного цикличного выполнения.
Следующее является примером того, на что код похож на практике;

class SpecialRule:
    """"""
    name="Special Rule"
    description="This is a Special Rule."
    def __init__(self, name=None):
        """"""
        print "SpecialInit"
        if name!=None:
            SPECIAL_RULES={
                "Fly" : FlyRule(),
                "Skirmish" : SkirmishRule()
                } #dictionary coupling names to SpecialRuleclasses
            self.__class__= SPECIAL_RULES[name].__class__

    def __str__(self):
        """"""
        return self.name

class FlyRule(SpecialRule):
    """"""
    name="Fly"
    description="Flies."
    def __init__(self):
        """"""
        print "FlyInit"+self.name
        SpecialRule.__init__(self)
    def addtocontainer(self, container):
        """this instance messes with the attributes of its containing class when added to some sort of list"""

class SkirmishRule(SpecialRule):
    """"""
    name="Skirmish"
    description="Skirmishes."
    def __init__(self):
        """"""
        SpecialRule.__init__(self)
    def addtocontainer(self, container):
        """this instance messes with the attributes of its containing class when added to some sort of list"""

test=SpecialRule("Fly")
print "evaluating resulting class"
print test.description
print test.__class__
</pre></code>

вывод:



> SpecialInit FlyInitFly SpecialInit evaluating resulting class Flies. main.FlyRule >

Существует ли больше pythonic решения и там обозримые проблемы с моим? (И действительно ли я ошибаюсь, который это - хорошая практика программирования для явного вызова .__init__(self) из родительского класса в .__init__ из подкласса?). Мое решение чувствует себя немного... неправильным...

Быстрое резюме до сих пор;
Спасибо за быстрые ответы

Решение Mark Tolonen
Я изучал __new__-method, но когда я пытаюсь сделать A, B и C в подклассах Mark Tolonen в качестве примера Z, я получаю ошибку, что класс Z еще не определяется. Также я не уверен при инстанцировании класса A, нормальный путь (с variable=A () за пределами объема Z) возможен, если Вы уже не имеете экземпляр сделанного подкласса и называете класс как атрибут экземпляра подкласса Z..., который не кажется очень простым. __new__ довольно интересно, таким образом, я буду дурачиться с ним немного больше, Ваш пример легче схватить, чем, что я получил от pythondocs.

Решение Greg Hewgill
Я попробовал staticmethod-решение, и это, кажется, хорошо работает. Я изучил использование отдельной функции как фабрика прежде, но я предположил, что станет трудным управлять большой программой со списком свободных скруток кода конструктора в основном блоке, таким образом, я буду очень рад интегрировать его в классе.
Я действительно экспериментировал немного наблюдения, если я мог бы превратить создавать-метод в украшенное .__call__() но это стало довольно грязным, таким образом, я оставлю его в этом.

5
задан Ben 1 August 2010 в 23:47
поделиться