Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Tvorba objektů podle řetězce

Aktivity
Avatar
Ondřej Krsička:8.2.2016 18:22

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.2.2016 18:22
Avatar
coells
Tvůrce
Avatar
Odpovídá na Ondřej Krsička
coells:8.2.2016 18:31
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.2.2016 18:31
Avatar
coells
Tvůrce
Avatar
Odpovídá na Ondřej Krsička
coells:8.2.2016 18:37

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í
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
8.2.2016 18:37
Avatar
hanpari
Tvůrce
Avatar
Odpovídá na Ondřej Krsička
hanpari:9.2.2016 18:28

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.2.2016 18:28
Avatar
Odpovídá na coells
Ondřej Krsička:9.2.2016 18:50

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.2.2016 18:50
Avatar
coells
Tvůrce
Avatar
Odpovídá na Ondřej Krsička
coells:9.2.2016 19:10

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.2.2016 19:10
Avatar
Odpovídá na coells
Ondřej Krsička:9.2.2016 19:35

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

 
Nahoru Odpovědět
9.2.2016 19:35
Avatar
coells
Tvůrce
Avatar
Odpovídá na Ondřej Krsička
coells:9.2.2016 20:47

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.2.2016 20:47
Avatar
hanpari
Tvůrce
Avatar
Odpovídá na coells
hanpari:9.2.2016 21:11

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.2.2016 21:11
Avatar
Odpovídá na hanpari
Ondřej Krsička:9.2.2016 22:32

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

 
Nahoru Odpovědět
9.2.2016 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.