Avatar
Ondřej Krsička
Redaktor
Avatar
Ondřej Krsička:

Ahoj. Řekněme, že mám řetězec "+-/--*+" a chci podle něj vytvořit pole objektů. Mám třídy Plus, Minus,Krat a Deleno. Jsou to potomci třídy Operator. Každá má metodu Pouzit a konstantu rozpoznávacího znaku(např "+").
Jak mám projít řetězec a podle něj vytvořit pole objektů stylem jiným, než tímto?

if retezec[i] == Plus.znak:
        objekty[i] = Plus()
elif retezec[i] == Minus.znak:
        objekty[i] = Minus()

Chtělo by to nějaký iterátor všech tříd, které dědí od Operator, který by to testoval. Chci to udělat tak, aby když přidám k operátorům třeba ^ jako mocninu, abych nemusel měnit tenhle kód, křerý řetězec mění na objekty.
Díky za odpovědi, Ondra.

 
Odpovědět 8. února 18:22
Avatar
coells
Redaktor
Avatar
Odpovídá na Ondřej Krsička
coells:
OPERACE = [Plus, Minus, Deleno]
operatory = {o.znak: o for o in OPERACE}

objekty = [operatory[r] for r in retezec]
# nebo
objekty = list(map(operatory.get, retezec))
 
Nahoru Odpovědět 8. února 18:31
Avatar
coells
Redaktor
Avatar
Odpovídá na Ondřej Krsička
coells:

A protože jsi v Pythonu, tak většinou není důvod, proč dědit od nějakého společného předka.
To jsou neřesti statických jazyků, Python nemá statické definice kontraktů.
Když už bys mermomocí chtěl mít společnost třídu, je v tom případě lepší mít jen jednu třídu Operator a zacházet s jejíma instancema.

Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
 
Nahoru Odpovědět 8. února 18:37
Avatar
hanpari
Redaktor
Avatar
Odpovídá na Ondřej Krsička
hanpari:

Předseda má pravdu, ty jsi asi chtěl něco jako pythoní switch.

operatory = {Plus.znak: Plus,
Minus.znak: Minus,
...
}

Použití:

minus = operatory["-"]()

 
Nahoru Odpovědět 9. února 18:28
Avatar
Ondřej Krsička
Redaktor
Avatar
Odpovídá na coells
Ondřej Krsička:

No, díky za snahu, omlouvám se za zbytečný dotaz a za ztracený čas. Nakonec jsem našel perfektní věc:

class Operator:
        pass
class Plus(Operator):
        pass
class Minus(Operator):
        pass

print(Operator.__subclasses__())

Ta metoda __subclasses__ je to, co jsem hledal :-) Zajímavé je, že mi ji IDLE v našeptávači neukázalo.

 
Nahoru Odpovědět 9. února 18:50
Avatar
coells
Redaktor
Avatar
Odpovídá na Ondřej Krsička
coells:

Tohle nedělej, tohle použití tříd není dobré a při čemkoliv složitějším to začne zlobit.
Lepší je jedna třída s instancema.

class Operator:

    def __init__(self, code):
        self.code = code

    def __repr__(self):
        return self.code

operators = [Operator('+'), Operator('-'), Operator('*')]
print(operators)
# nebo
operators = [Operator(i) for i in '+-*']
print(operators)
 
Nahoru Odpovědět 9. února 19:10
Avatar
Ondřej Krsička
Redaktor
Avatar
Odpovídá na coells
Ondřej Krsička:

No, každý operátor má bohužel jinou metodu. Každopádně díky za tip do budoucna.

 
Nahoru Odpovědět 9. února 19:35
Avatar
coells
Redaktor
Avatar
Odpovídá na Ondřej Krsička
coells:

No a? Jsi v pythonu, funkce je first-class citizen, je to o to jednodušší, pokud je to jedna metoda.

 
Nahoru Odpovědět 9. února 20:47
Avatar
hanpari
Redaktor
Avatar
Odpovídá na coells
hanpari:

Tady jsi na devbooku, tady máme rádi OOP :)

Ale vážně, Ondřeji, nedělej věci komplikovaně, když je můžeš dělat jednoduše.
To je velmi oficiální doporučení:
https://www.youtube.com/watch?…

 
Nahoru Odpovědět 9. února 21:11
Avatar
Ondřej Krsička
Redaktor
Avatar
Odpovídá na hanpari
Ondřej Krsička:

To ten Python asi moc neumím :D Díky za doporučení.

 
Nahoru Odpovědět  +1 9. února 22:32
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 10.