Python - zbožňovaný lidmi?

ByCzech

  • *****
  • 1 861
    • Zobrazit profil
    • E-mail
Re:Python - zbožňovaný lidmi?
« Odpověď #45 kdy: 12. 09. 2017, 20:22:05 »
A který to má být ten netypovaný jazyk v daném kontextu?

Python

To je pro mě novinka, když Python má silnou typovou kontrolu :)


noef

  • *****
  • 897
    • Zobrazit profil
    • E-mail
Re:Python - zbožňovaný lidmi?
« Odpověď #46 kdy: 13. 09. 2017, 07:20:36 »
Zajímavé, mě tohle vůbec nechybí. Vícenásobné interfaces mi stačí.

Mně to taky moc nechybělo, dokud jsem si nevyzkoušel mixiny v pythonu. A to jsem v podstatě pythonní začátečník. Jednoduchost přidání další funcionality (nejen předpisu ala vícenásobný interface v javě) k jakékoliv kompatibilní třídě je fakt příjemná. Jenom kdyby se to tak dalo pořádně typovat...

Uz jsem chtel napsat, ze dokud jsem si traity/mixiny* trochu nevyzkousel, tak me pochopitelne nechybely. Ale podobne je to i s opravdovymi typy a typovou inferenci ala Haskell. Jakmile jsem ji ochutnal, tak najednou vsude vidim jak jsou typove systemy slabe a jak jsou jazyky navrzene tak, ze inference je znacne omezena (Scala - protoze OOP) nebo je proste prekladac hloupy (TypeScript - mladost projektu?).

Muzete zkusit Scalu, ta ma traity, lepsi typovy system nez Java a bezi nad JVM ;).

PS: Co se divam na definice, tak traity ve Scale jsou asi spise mixiny.

DotNetGuy

Re:Python - zbožňovaný lidmi?
« Odpověď #47 kdy: 13. 09. 2017, 07:34:24 »
to me poser. tady resite sracky typu python, java a ani poradne neumite jak to vsechno funguje a co se odehrava v pocitaci. ja delam uz pres 20 let v assembleru. hodne z vas v tom neumi napsat ani hello world, ale jo klidne si tady dokazujte, ze jste borci
+1, to ví dneska už jen málokdo.

dustin

Re:Python - zbožňovaný lidmi?
« Odpověď #48 kdy: 13. 09. 2017, 08:54:36 »
Přímo v assembleru asi ne, ale v céčku si s jednočipy hraje docela dost lidí. Zrovna ten můj pythonní projekt má na druhé straně sériového portu STM32 s TFT dotykem.

Ale ten argument je mimo. Někdo řeší embedded detaily hardwaru v C/asm, někdo potřebuje rychle vytvořit prototypy nebo vědecké programy v pythonu, někdo designuje rozsáhlé systémy v javě. Vše z toho je důležité a na každé z toho se hodí jiný jazyk. Ale to přece všichni víme.

Lemming

Re:Python - zbožňovaný lidmi?
« Odpověď #49 kdy: 13. 09. 2017, 08:57:40 »
to me poser. tady resite sracky typu python, java a ani poradne neumite jak to vsechno funguje a co se odehrava v pocitaci. ja delam uz pres 20 let v assembleru. hodne z vas v tom neumi napsat ani hello world, ale jo klidne si tady dokazujte, ze jste borci

Jen 20 let? To já začal s assemblerem někdy v roce 1990. Takže hezky zavři kušnu, mlíčňáku, a nepleť se mezi zkušený borce. 8)

Jednoduchost přidání další funcionality (nejen předpisu ala vícenásobný interface v javě) k jakékoliv kompatibilní třídě je fakt příjemná.

To, že je něco jednoduché neznamená, že je to správné. Že třída implementuje víc rozhraní, to jistě, to je šikovné a velmi často dává smysl. Ale přidávat tam i implementaci mi připadá spíš jako zneužívání dědičnosti (*), které by bylo čistší vyřešit skládáním. Dokážete hodit nějaké ne-za-vlasy-přitažené příklady, kdy je takovéhle využívání mixinů architektonicky správné?

*) Něco jako když si programátor definuje utility funkci v nadtřídě a využívá ji z podtříd, místo co by ji vyčlenil do utility class.


dustin

Re:Python - zbožňovaný lidmi?
« Odpověď #50 kdy: 13. 09. 2017, 09:53:07 »
Ale přidávat tam i implementaci mi připadá spíš jako zneužívání dědičnosti (*), které by bylo čistší vyřešit skládáním. Dokážete hodit nějaké ne-za-vlasy-přitažené příklady, kdy je takovéhle využívání mixinů architektonicky správné?

*) Něco jako když si programátor definuje utility funkci v nadtřídě a využívá ji z podtříd, místo co by ji vyčlenil do utility class.

Nejsem žádný specialista na mixiny, ale tady jde právě o skládání. Dědičnost v řadě případů nefunguje, protože stejnou funkcionalitu potřebuji např. u dvou potomků z různých větví dědičnosti. Přesně to, o čem mluvíš - musel bych to dát do společného předka, který je hluboko v řetězci a nemá s tím nic společného, nebo do externí utils třídy. Proto se to poskládá mixiny. Přímá dědičnost je vlastně jeden mixin.

Příklad, kde jsem to využil (neříkám, že by to nešlo jinak, v javě se to řeší např. kompozicí):

Mám ve websockets aplikaci různé boxy (divy), který se na nějaký povel otevřou. Jsou to potomci různých dědičných levelů základního boxu s různými funkcionalitami. A u některých chci, aby se při nečinnosti uživatele po chvíli zase zavřely a zobrazil se předchozí box.

Mixin TimedClose pro zavírání:
https://github.com/pavhofman/aio/blob/master/uis/timedclose.py#L11

Přidám jej do boxů, které mají různé předky:
https://github.com/pavhofman/aio/blob/master/uis/volumefsbox.py#L17 - předkem je Widget (změním hlasitost a po chvíli se okno zavře do původní obrazovky)
https://github.com/pavhofman/aio/blob/master/uis/activatesourcefsbox.py#L10 - předkem je HBox -> Widget (nabídka zdrojů signálu, když na nic nekliknu, zase se to samo zavře)

Box se po čase daném v konstruktoru TimedClose zavře sám, případně jej zavře nadřazená aplikace
https://github.com/pavhofman/aio/blob/master/uis/webapp.py#L82

Takových boxů je v projektu celá řada. U jiných to dneska nechci - např. box pro průchod stromem pro výběr dalšího přehrávaného tracku/adresáře https://github.com/pavhofman/aio/blob/master/uis/nodeselectfsbox.py#L25 . A třeba se časem rozhodnu, že by bylo uživatelsky lepší jej autozavírat - stačí přidat TimedClose do seznamu jeho mixinů.

To samé třeba mixin AddPlaybackButtons https://github.com/pavhofman/aio/blob/master/uis/addsplaybackbuttons.py#L16 , který každému boxu s tímto mixinem přidává tlačítka na přehrávání a kompletně ošetřuje jejich volání. Takže se mohu (i později) rozhodnout, ve kterých boxech z uživatelského rozhraní ta tlačítka budou, nezávisle na dědičné linii těch boxů.


Jenže by se mi líbilo, kdybych TimedClose mohl říct, pro jaké třídy je určený (vyžaduje existenci fieldu self._app typu WebApp). V javě by se použila klasická parametrizovaná generika, v pythonu jsem na to nepřišel. Samozřejmě mohu použít runtime kontrolu, což je IMO děs (např. super knihovna remi https://github.com/dddomodossola/remi/blob/master/remi/gui.py#L465 , nebo jiný příklad https://github.com/mopidy/mopidy/blob/develop/mopidy/internal/validation.py#L75 ). Samozřejmě se jedná jen o hint pro IDE (což je stejně případ všech těch type-hintů, pythonnímu interpretu je to fuk), ale ani to jsem nikde nenašel. Parametrizovaná generika https://docs.python.org/3/library/typing.html#generics používám, ale potřeboval bych něco jako <T extends AppBox>

Ten odkazovaný projekt je rozpracovaný prototyp, chybí tam spoustu věcí...

V javě jde třídu rozšířit jen interfacem, proto se její vývojáři snaží trochu o workaround a přidávají funkcionalitu do interfaců. Java 8 má v interfacech defaultní implementované metody, java 9 přidává privátní metody. Bohužel pro plnou funkci chybí interní fieldy, aby si to mohlo udržovat stav, ale tímhle směrem to asi nepůjde.

dustin

Re:Python - zbožňovaný lidmi?
« Odpověď #51 kdy: 13. 09. 2017, 10:00:09 »
Koukám, že do těch mixinů tu app předávám v konstruktoru, takže to omezení na využití neplatí. Ale jinde by se to hodilo, kdybych v mixinu používal metody třídy, kterou mixin rozšiřuje. Což uznávám není úplně čisté...

gll

Re:Python - zbožňovaný lidmi?
« Odpověď #52 kdy: 13. 09. 2017, 11:21:09 »
na podobné věci používám class dekorátory, ale s typováním by se to asi bilo ještě víc. Už jste zkoušel Kotlin?

dustin

Re:Python - zbožňovaný lidmi?
« Odpověď #53 kdy: 13. 09. 2017, 11:45:56 »
Class dekorátory jsem ještě nepoužíval, díky, mrknu na ně.

Jak říkám, typování je pro mě klíčové, nemám rád tápání, co má být jaký typ. Když už to nehlídá (neexistující) kompilátor, tak aby to hlídalo alespoň IDE.

Nové jazyky jsou fajn a z mého pohledu důležité jako inspirace pro další vývoj těch dinosauřích (za mě java a python). Ale když něco dělám, tak jednak chci kvalitní knihovny na vše možné, jednak chci delší použitelnost a znovuvyužitelnost kódu, než jen pár let, kdy je novinka zrovna in. Nedělám to jen tak na vyzkoušení, ten přístroj bude muset šlapat spoustu let a občas bude potřeba jeho software upravovat/rozšiřovat/aktualizovat na nové knihovny/překladač/JVM atd. Stejně jako všechny živé a používané systémy. Takže ani v Kotlinu, ani ve Scale své projekty psát nebudu, nejsou to zápočťáky, které pak zahodím. Obávám se tedy, že se k nim hned tak nedostanu, času (proflákaného diskusemi na netu) málo...

gll

Re:Python - zbožňovaný lidmi?
« Odpověď #54 kdy: 13. 09. 2017, 11:49:46 »
Jenže by se mi líbilo, kdybych TimedClose mohl říct, pro jaké třídy je určený (vyžaduje existenci fieldu self._app typu WebApp)

Podle mě tohle vyřeší protokoly https://www.python.org/dev/peps/pep-0544/. Mixin je předek a neměl by explicitně znát typ potomka. V souboru Mixinu definujete protokol a nemusíte importovat potomka.

Lemming

Re:Python - zbožňovaný lidmi?
« Odpověď #55 kdy: 13. 09. 2017, 12:56:08 »
Příklad, kde jsem to využil (neříkám, že by to nešlo jinak, v javě se to řeší např. kompozicí):
...

Díky za osvětlení. Mě to tedy moc elegantní nepřijde, a kód stylu

Citace
if isinstance(box, TimedClose):
            box.activateTimer()

mi naopak přijde těžce neelegantní (slušně řečeno). Napsat totéž skládáním mi nepřijde o nic horší.

Mimochodem, v Java web frameworku Wicket bych pro podobnou věc použil něco čemu říkají "Behavior". To je potomek třídy Behavior, který se dá přidat na jakoukoli komponentu a má volání dostává volání podle životního cyklu té komponenty. Takže bych udělal třídu:

Citace
import org.apache.wicket.ajax.AbstractAjaxTimerBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;

public class HideBehavior extends AbstractAjaxTimerBehavior {
  @Override
  protected void onTimer(AjaxRequestTarget target) {
    getComponent().setVisible(false);
  }
}

Pak prostě můžeš udělat třeba:

Citace
  component.add(new HideBehavior(Duration.seconds(10)));

a komponenta se ti po daném timeoutu skryje. Tomu _já_ říkám elegance :)

gll

Re:Python - zbožňovaný lidmi?
« Odpověď #56 kdy: 13. 09. 2017, 13:03:15 »
a komponenta se ti po daném timeoutu skryje. Tomu _já_ říkám elegance :)

Z dokumentace "A behavior that generates an AJAX update callback at a regular interval.". V době podpory websocketů ve všech prohlížečích si elegantní řešení představuji jinak.

kobra

Re:Python - zbožňovaný lidmi?
« Odpověď #57 kdy: 13. 09. 2017, 13:22:55 »
a komponenta se ti po daném timeoutu skryje. Tomu _já_ říkám elegance :)

Z dokumentace "A behavior that generates an AJAX update callback at a regular interval.". V době podpory websocketů ve všech prohlížečích si elegantní řešení představuji jinak.

Websocket vyzaduje trvale otevreny kanal, coz je v ere mobilni dost nezadouci. Z hlediska uzivatele je uplne jedno jestli ti server pushuje pres socket kazdou pulminutu nebo to udela setinterval pres ajax.

wsh

Re:Python - zbožňovaný lidmi?
« Odpověď #58 kdy: 13. 09. 2017, 13:24:06 »
Dokážete hodit nějaké ne-za-vlasy-přitažené příklady, kdy je takovéhle využívání mixinů architektonicky správné?

Nevím, jestli je to architektonicky správné, ale v praxi se mixiny velice dobře používají. Příkladem může být sada mixinů Django Braces, které můžu přidat podle potřeby k libovolnému View (v terminologii jiných MVC by to byl spíš controller).

SSLRequiredMixin:
doc: https://django-braces.readthedocs.io/en/latest/access.html#sslrequiredmixin
implementace: https://github.com/brack3t/django-braces/blob/master/braces/views/_access.py#L344

Zároveň jsou Braces i příkladem toho, co je na mixinech špatně. Snaha o maximální DRY v Djangu vedla k tak chaotické hierarchii tříd a mixinů (http://bit.ly/2h0yEMh), že vznikl externí projekt Braces, který řeší to stejné, ale jednodušeji a přehledněji.

gll

Re:Python - zbožňovaný lidmi?
« Odpověď #59 kdy: 13. 09. 2017, 13:25:54 »
a komponenta se ti po daném timeoutu skryje. Tomu _já_ říkám elegance :)

Z dokumentace "A behavior that generates an AJAX update callback at a regular interval.". V době podpory websocketů ve všech prohlížečích si elegantní řešení představuji jinak.

Websocket vyzaduje trvale otevreny kanal, coz je v ere mobilni dost nezadouci. Z hlediska uzivatele je uplne jedno jestli ti server pushuje pres socket kazdou pulminutu nebo to udela setinterval pres ajax.

Server pushne jen když nastane událost.