Aulas virtuais: fazendo certo?

estive a ler documentação que descreve a herança de classes, as classes de base abstractas e até as interfaces python. Mas nada parece ser exactamente o que eu quero. Ou seja, uma forma simples de construir aulas virtuais. Quando a classe virtual é chamada, Eu gostaria que ela instanciasse alguma classe mais específica com base em quais os parâmetros que ela é dada e entregar de volta a função de chamada. Por agora, tenho uma forma resumida de reencaminhar chamadas para a classe virtual para a base subjacente. classe.

a ideia é a seguinte:

class Shape:
    def __init__(self, description):
        if   description == "It's flat":  self.underlying_class = Line(description)
        elif description == "It's spiky": self.underlying_class = Triangle(description)
        elif description == "It's big":   self.underlying_class = Rectangle(description)
    def number_of_edges(self, parameters):
        return self.underlying_class(parameters)

class Line:
    def __init__(self, description):
        self.desc = description
    def number_of_edges(self, parameters):
        return 1

class Triangle:
    def __init__(self, description):
        self.desc = description
    def number_of_edges(self, parameters):
        return 3

class Rectangle:
    def __init__(self, description):
        self.desc = description
    def number_of_edges(self, parameters):
        return 4

shape_dont_know_what_it_is = Shape("It's big")
shape_dont_know_what_it_is.number_of_edges(parameters)
O meu reencaminhamento está longe de ser óptimo, pois só as chamadas para a função number_ of_edges() são passadas. Adicionar algo assim à forma também não se entrelaça para fazer o truque:

def __getattr__(self, *args):
    return underlying_class.__getattr__(*args)
O que estou a fazer de errado ? Toda esta ideia está mal implementada ? Qualquer ajuda muito apreciada.

Author: martineau, 2010-06-19

4 answers

Preferia fazê-lo com uma fábrica.
def factory(description):
    if   description == "It's flat":  return Line(description)
    elif description == "It's spiky": return Triangle(description)
    elif description == "It's big":   return Rectangle(description)

Ou:

def factory(description):
    classDict = {"It's flat":Line("It's flat"), "It's spiky":Triangle("It's spiky"), "It's big":Rectangle("It's big")}
    return classDict[description]

E herdar as classes da forma

class Line(Shape):
    def __init__(self, description):
        self.desc = description
    def number_of_edges(self, parameters):
        return 1
 14
Author: TooAngel, 2016-01-25 15:29:23

Concordo com TooAngel, mas eu usaria o __novo__ método.

class Shape(object):
    def __new__(cls, *args, **kwargs):
        if cls is Shape:                            # <-- required because Line's
            description, args = args[0], args[1:]   #     __new__ method is the
            if description == "It's flat":          #     same as Shape's
                new_cls = Line
            else:
                raise ValueError("Invalid description: {}.".format(description))
        else:
            new_cls = cls
        return super(Shape, cls).__new__(new_cls, *args, **kwargs)

    def number_of_edges(self):
        return "A shape can have many edges…"

class Line(Shape):
    def number_of_edges(self):
        return 1

class SomeShape(Shape):
    pass

>>> l1 = Shape("It's flat")
>>> l1.number_of_edges()
1
>>> l2 = Line()
>>> l2.number_of_edges()
1
>>> u = SomeShape()
>>> u.number_of_edges()
'A shape can have many edges…'
>>> s = Shape("Hexagon")
ValueError: Invalid description: Hexagon.
 18
Author: Georg Schölly, 2017-05-23 12:09:49

O Python não tem classes virtuais fora da caixa. Você terá que implementá-los você mesmo (deve ser possível, as capacidades de reflexão do Python deve ser poderoso o suficiente para permitir que você faça isso).

No entanto, se precisa de aulas virtuais, porque não usa uma linguagem de programação que tenha aulas virtuais como Beta, gBeta ou Novilíngua? (BTW:existem outros?) No entanto, neste caso em particular, não vejo como classes virtuais simplificariam a sua solução, pelo menos não no exemplo que deu. Talvez possas explicar porque achas que precisas de aulas virtuais? Não me interprete mal: eu gosto de aulas virtuais, mas o fato de que apenas três línguas já as implementaram, apenas uma dessas três ainda está viva e exatamente 0 dessas três são realmente usadas por qualquer um é um pouco Revelador ... {[[2]}
 1
Author: Jörg W Mittag, 2010-06-19 17:55:56
 0