Python - circular importy v type hintech

dustin

Python - circular importy v type hintech
« kdy: 17. 06. 2017, 12:46:50 »
Nedávno tu proběhla debata o pozici pythonu jako kvalitním programovacím jazyku. Mohu tedy poprosit místní gurus o úplně základní radu?

Jsem javista. Doma dělám na soukromém projektu v pythonu, protože už mám nějaký kód z dřívějška a (zatím) se mi to nechce přepisovat do javy. Používám pycharm, python 3.4 v Mintu 18.

Snažím se psát objektově, protože jsem na to zvyklý. Současně mám rád v jednom souboru jednu "public" třídu (může obsahovat i "privátní", které se nepoužívají jinde). Samozřejmě chci používat v maximální míře typehinty, abych se v kódu vyznal a maximálně využil možnosti IDE. Bohužel typehinty vyžadují importy a vedou přímo na zakázané circular importy. Diskuse bez rozumného závěru je např. https://github.com/python/typing/issues/105 , https://stackoverflow.com/questions/39740632/python-type-hinting-without-cyclic-imports .

Doporučuje se:

forward reference jako string - i pro tu chce IDE import statement, aby věděl, kde to najít

import xxxxxx bez from  a v kódu použít celou cestu - mám projekt ve vnořených modulech, abych to měl aspoň trochu rozdělené. Typehinty jsou pak hodně dlouhé - lze to prosím nějak naaliasovat, abych pokaždé nemusel uvádět celou cestu?

I tak mi to nefunguje - příklad:

Modul ui (s __init__.py) -> soubor webui.py -> class WebUI.

Ve stejném adresáři chci ve třídě ui/webapp.py-> class WebApp  v metodě volané zvenku označit typehintem třídu WebUI. Ta ale vytváří instanci třídy WebApp, tudíž samozřejmě má soubor webap.py importovaný.

Zkusím standardní import:

Kód: [Vybrat]
from uis.webui import WebUI
...
def main(self, webui: WebUI):

Klasický circular import vzniklý pouhým typehintováním WebUI, nogo.

Dobře, zkusím variantu pouhého importu

Kód: [Vybrat]
import ui.webui
...
def main(self, webui: uis.webui.WebUI):

Výsledkem je

Kód: [Vybrat]
AttributeError: module 'uis' has no attribute 'webui'
Samozřejmě mohu nic neimportovat, WebUI dát jako string, ignorovat chybu IDE, že daný typ nezná a rezignovat na jakékoliv nabídky proměnných atd. Takový vývoj je mi však silně proti srsti.

Mohu poprosit o zkušenosti, jak v praxi řešíte typehinty a circular importy? Předem díky moc.


dustin

Re:Python - circular importy v type hintech
« Odpověď #1 kdy: 17. 06. 2017, 12:56:17 »
Oprava příspěvku - ten modul se jmenuje uis (adresář uis), tedy nefunkční import je správně:

Kód: [Vybrat]
import uis.webui
"ui" je jenom překlep na několika místech v needitovatelném příspěvku.

dustin

Re:Python - circular importy v type hintech
« Odpověď #2 kdy: 17. 06. 2017, 13:54:58 »
Aha, pro tohle je určena podmínka

Kód: [Vybrat]
if TYPE_CHECKING:
  from xxxx import yyyy

https://docs.python.org/3/library/typing.html#typing.TYPE_CHECKING

Nic moc, protože to IDE negeneruje samo (narozdíl od importu), tudíž se na to bude zapomínat. Ale budiž, dá se.

gll

Re:Python - circular importy v type hintech
« Odpověď #3 kdy: 17. 06. 2017, 14:58:57 »

dustin

Re:Python - circular importy v type hintech
« Odpověď #4 kdy: 17. 06. 2017, 15:32:58 »
Interfacy mají také  typehinty, co když bude smyčka v deklaracích svých metod (AInterface má metodu s parametrem typu BInterface a naopak)? Jak to pak vyřeší interfacy místo konkrétních implementací? Ten hack s podmíněným importem jo, do mi dává smysl.


gll

Re:Python - circular importy v type hintech
« Odpověď #5 kdy: 17. 06. 2017, 16:41:40 »
Interfacy mají také  typehinty, co když bude smyčka v deklaracích svých metod (AInterface má metodu s parametrem typu BInterface a naopak)? Jak to pak vyřeší interfacy místo konkrétních implementací? Ten hack s podmíněným importem jo, do mi dává smysl.

V AInterface se volá metoda z BInterface s parametrem AInterface? Pokud ne, tak bych tu metodu dal do jiného interface a odstranil závislost BInterface na AInterface.

gll

Re:Python - circular importy v type hintech
« Odpověď #6 kdy: 02. 07. 2017, 01:38:38 »
Protokoly všechny problémy s importy docela dobře řeší

https://www.python.org/dev/peps/pep-0544/

bude to součástí 3.7., ale můžete to používat už teď.

https://www.python.org/dev/peps/pep-0544/#implementation


dustin

Re:Python - circular importy v type hintech
« Odpověď #7 kdy: 02. 07. 2017, 08:19:00 »
Ten text jsem jenom prolétl. Pokud jsem to pochopil, řeší problém s circular importem, pokud by všechny mé třídy měly předpisy protokoly a jako typy bych používal je (protože se údajně nemusí importovat). To mi přijde ještě daleko nepraktičtější, než typehintové importy dát do if TYPE_CHECKING, což funguje OK.

gll

Re:Python - circular importy v type hintech
« Odpověď #8 kdy: 02. 07. 2017, 08:35:00 »
Ten text jsem jenom prolétl. Pokud jsem to pochopil, řeší problém s circular importem, pokud by všechny mé třídy měly předpisy protokoly a jako typy bych používal je (protože se údajně nemusí importovat). To mi přijde ještě daleko nepraktičtější, než typehintové importy dát do if TYPE_CHECKING, což funguje OK.

v místě, kde byste musel jen kvůli typu použít cirkulární import, si místo něho můžete definovat protokol. Asi není třeba to používat všude.




dustin

Re:Python - circular importy v type hintech
« Odpověď #9 kdy: 02. 07. 2017, 09:08:15 »
To mohu, ale přece nebudu dodělávat protokoly zpětně u některých víceméně náhodně vybraných tříd (kde zrovna došlo k circular importu). Ty by měly sloužit k něčemu koncepčnímu, ne k zpětnému řešení nedokonalosti ekosystému jazyka (type hinty dolepené později + IDE vyžadující importy, aby se v tom vyznalo). To je větší hack, než stejným pracným a hloupým postupem spustit/chyba/opravit přesunut kolizní importy do type-checking podmínky.

deda

Re:Python - circular importy v type hintech
« Odpověď #10 kdy: 02. 07. 2017, 11:33:39 »
Nedávno tu proběhla debata o pozici pythonu jako kvalitním programovacím jazyku.

Myslím, že po pár příspěvcích je jasné, že to bylo asi myšleno jen jako vtip. Na skriptíky pro admina je to jazyk velmi dobrý, ale na vývoj to není.

Mantak

Re:Python - circular importy v type hintech
« Odpověď #11 kdy: 02. 07. 2017, 13:26:29 »
Python není Java tak se tam nesnaž naroubovat něco co používáš v Javě.

Re:Python - circular importy v type hintech
« Odpověď #12 kdy: 02. 07. 2017, 14:03:02 »
...
Myslím, že po pár příspěvcích je jasné, že to bylo asi myšleno jen jako vtip. Na skriptíky pro admina je to jazyk velmi dobrý, ale na vývoj to není.

 ;D  :D  :)
Javamane?

Ondrej

Re:Python - circular importy v type hintech
« Odpověď #13 kdy: 02. 07. 2017, 14:07:28 »
...
Myslím, že po pár příspěvcích je jasné, že to bylo asi myšleno jen jako vtip. Na skriptíky pro admina je to jazyk velmi dobrý, ale na vývoj to není.

 ;D  :D  :)
Javamane?
nebo lopato...

dustin

Re:Python - circular importy v type hintech
« Odpověď #14 kdy: 02. 07. 2017, 15:43:29 »
Python není Java tak se tam nesnaž naroubovat něco co používáš v Javě.

Nejde o javu, ale o typy. Nedovedu si představit, jak efektivně vyvíjet projekt už o pár desítkách tříd bez typů. Očividně to pálí spoustu lidí, když v poslední době vzniklo několik na sebe navazujících PEPů, které se to nějakým způsobem snaží řešit.

Jinak se mi python docela líbí, hlavně má pěkné snadno použitelné knihovny pro linux, které ve svém projektu výhodně využiji (udev, alsa, integrace s mpv/mopidy, atd.). Ale je pravda, že kdybych nyní začal od nuly, už bych do něj nešel, ta slabá možnost refaktorizace a dost syrové type hinty v IDE (pycharm) dost zdržují.