2016-09-05 2 views
1

Я пытаюсь написать метод, который должен вернуть мне объект подкласса в зависимости от некоторых входных данных. Позвольте мне объяснитьКак вернуть объект соответствия подкласса?

class Pet(): 
    @classmethod 
    def parse(cls,data): 
     #return Pet() if all else fails 
     pass 

class BigPet(Pet): 
    size = "big" 

    @classmethod 
    def parse(cls,data): 
     #return BigPet() if all subclass parsers fails 
     pass   

class SmallPet(Pet): 
    size = "small" 

    @classmethod 
    def parse(cls,data): 
     #return SmallPet() if all subclass parsers fails 
     pass 

class Cat(SmallPet): 
    sound = "maw" 

    @classmethod 
    def parse(cls,data): 
     #return Cat() if all criteria met 
     pass 

class Dog(BigPet): 
    sound = "woof" 

    @classmethod 
    def parse(cls,data): 
     #return Dog() if all criteria met 
     pass 

Представьте себе, что я хотел бы сделать «анализатор», например, это:

Pet.parse(["big", "woof"]) 
> returns object of class Dog 

Pet.parse(["small", "maw"]) 
> returns object of class Cat 

Pet.parse(["small", "blup"]) 
> returns object of class SmallPet 

Я не имею ни малейшего представления о том, как писать это в надлежащем порядке. Какие-либо предложения? Конечно, это пример дерьма. Я хотел бы применить это к различным пакетам какого-либо протокола связи.

Если я подхожу это совершенно неправильно, скажите, пожалуйста :)

ответ

0

Почему бы не передать точное имя класса, обратите внимание на том, что в globals() и экземпляр этого?

def parse_pet(class_name, data): 
    # will raise a KeyError exception if class_name doesn't exist 
    cls = globals()[class_name] 
    return cls(data) 

cat = parse_pet('Cat', 'meow') 
big_pet = parse_pet('BigPet', 'woof') 
+0

Потому что я мог бы так написать: кота = Cat (арг) big_pet = BigPet (арг) Ищу метод класса в некотором корневом классе, который вызывает ту же перекрытую функцию во все его чтобы увидеть, есть ли лучшее совпадение. – chrisvp

+0

Для вашего встречного предложения потребуется очень большая, поддерживаемая разработчиком карта между строками и классами, и ваше второе предложение, похоже, не имеет очевидного обоснования или преимущества. Большинство сериализаторов сопоставляют строки непосредственно с именами классов или типами. – Soviut

+0

Возможно, но ваше предложение предполагает, что я держу карту на бумаге, вручную проверяю каждый пакет и возвращаю объект типа, который мне нравится. Должен быть другой способ – chrisvp