Portál AbcLinuxu, 30. dubna 2025 11:33
@contextlib.contextmanager def TempDir(): path = tempfile.mkdtemp() yield path shutil.rmtree(path, True)
with TempDir() as tmpPath: … subprocess.check_call(["ghostscript", "-o", os.path.join(tmpPath, "%s.jpg")] + args) …Poznámka: ne, fakt to není nic objevného. To že je to takhle jednoduché se mi právě líbí. Poznámka pro pythonisty kteří nehoví kontext managerům: příklad si z toho neberte, tohle je dost nestandartní způsob jak to dělat. Pro zvědavé nepythonisty: v podstatě to funguje tak že na začátku with bloku se zavolá to co je před yield a na konci ten zbytek. Hlavní vtip je v tom že i když vystřelí výjimka, tak po sobě program způsobně uklidí a pak se výjimka propaguje dál. (V produkčním kódu se úklid nechá ladícím příznakem vypnout.)
Tiskni
Sdílej:
Pořád mi to přijde neohrabané. Třeba v Perlu stačí napsat:
{ my $tmpPath = File::Temp->newdir; IPC::Run3::run3(['ghostscript', '-o', File::Spec->cat($tmpPath, '%s.jpg'), @args]); }
Vtip je v tom, že metoda newdir() třídy File::Temp vrátí objekt, jehož destruktor standardně (lze potlačit) vyrobený adresář smaže. A destruktor se zavolá v okamžiku, kdy program opustí blok. (Včetně vyvolání výjimky.)
finally
...
V Javě na to máme rozhraní AutoCloseable
. Takže napíšeš:
try (TřebaAdresář zdroj = kdeSeVezme()) { // tady s tím zdrojem něco děláme // a může vyletět výjimka }
Je jedno, jestli je tam i catch
blok a jestli nějaká výjimka vyletí – zdroj se prostě na konci try
bloku (nebo při chybě) sám korektně uzavře (zavolá se jeho metoda close()
).
kdeSeVezme()
?
Zdroj se ani nevytvoří, takže ho není potřeba zavírat.
A výjimku můžeš zachytit v daném try/catch bloku:
try (Connection c = DriverManager.getConnection("…")) { // děláme něco se spojením } catch (SQLException e) { // ošetříme výjimku }
nebo v nějakém vyšším nebo ji poslat nahoru.
getConnection()
vyhodí SQLException
, tak to skočí na ten catch
block a tělo try
se nevykoná, chápu to správně?
Přidal jsem do výběru
Ale k věci – na tom:
@contextlib.contextmanager def TempDir(): path = tempfile.mkdtemp() yield path shutil.rmtree(path, True)
mi prostě nějak nesedí, že kód pro vytvoření (konstruktor?) a kód pro úklid (destruktor?) jsou v jednom bloku a na základě nějaké magie se udělá část bloku teď a část potom. Víc se mi líbí explicitnější vyjádření, kde mám jednu metodu/blok pro vytvoření a druhou pro úklid.
To je normální, Python řeší věci ... po svém.Pokud vím, tak context manager interface jde v Pythonu triviálně implementovat třídou. To, že někdo vymýšlí cypoviny typu contextlib.contextmanager na tom nic nemění.
yield path
a shutil.rmtree(path, True)
by malo byť v try: finally
, pretože ak tá funkcia subprocess.check_call vyvolá výnimku, ten súbor sa nevymaže.
a nerikam, ze java je nej... neni. ale nedovoli podradnym radobyprogramatorum az tak moc prasit.Už jsem se vyrovnal s tím, že tenhle mýtus je ve světě Javy světě prakticky nevymýtitelný... Je to něco jako ta teorie o tom, že letadlo letí proto, že vzduch na vrchní straně křídel proudí rychleji - naprostý nesmysl, ale i velmi chytří lidé ho neustále opakují...
Už jsem se vyrovnal s tím, že tenhle mýtus je ve světě Javy světě prakticky nevymýtitelný.
Četl jsem javovský kód pro ne moc dobrých programátorech a člověk si občas zanadává, to jo, ale nakonec se s tím popereš, refaktoruješ to, opravíš – dá se na tom stavět. A pak jsem měl zdrojáky v pythonu nebo pascalu, které bylo lepší zahodit, prokousat se sám zadáním nebo to vymyslet znova, než se je pokoušet opravovat.
A za jeho blbost může Java jak?
Já neříkal, že v Javě nejde psát špatně, ale aspoň je vidět, co je špatně a dá se v tom vyznat, víš, co by to mělo dělat, je z toho lépe vidět ten záměr autora, dá se to přepsat, refaktorovat (aniž by se ti to rozsypalo pod rukama).
A za jeho blbost může Java jak?Nijak. Já neříkal, že za to může Java.
Já neříkal, že v Javě nejde psát špatně, ale aspoň je vidět, co je špatně a dá se v tom vyznat, víš, co by to mělo dělat, je z toho lépe vidět ten záměr autora, dá se to přepsat, refaktorovat (aniž by se ti to rozsypalo pod rukama).To jsou kecy. Situace je v podstatě stejná jako u ostatních jazyků, výjimku by tvořil snad jen assembler. Tobě to v Javě připadá jasnější/přehlednšjí, protože Javu (zřejmě) znáš nejlépe.
Co je na Windows "entrprajs"? Vždyť je to spotřební odpad. Enterprise jsou velké servery, na kterých běží Unix, Solaris, OpenVMS, HP-UX, AIX nebo dneska čím dál víc GNU/Linux a provozují se nad tím velké relační databáze (ne jejich parodie), LDAPy o desítkách milionech záznamů, Java EE a podobné věci.
Já neříkal, že v Javě nejde psát špatně, ale aspoň je vidět, co je špatně a dá se v tom vyznat, víš, co by to mělo dělat, je z toho lépe vidět ten záměr autora, dá se to přepsat, refaktorovat (aniž by se ti to rozsypalo pod rukama).Ne, ne, ne, špatně. Pointa je úplně jinde: i zprasenou aplikaci lze provozovat. TO je to slavné "enterprajs". Prostě se kód hodí někomu trochu schopnějšímu a ten do termínu nějak zafixuje ty nejhorší problémy a doplní pár ohejbáků a rovnáků na ohejbáky. Pak se při instalaci přihodí se párkrát víc paměti (a/nebo víc serverů), v nejhorším se dá do cronu restart jednou za čas v noci a oficiálně oznámí "plánovaná odstávka" - a hotovo. Zákazník platí (možná brblá že je to pomalé a vůbec, ale platí). Všichni se poplácají po rameni za úspěšně dokončený projekt, možná i prémie budou. A už se může připravovat další projekt - při troše štěstí to bude projekt "přepis sračky A" Rozdíl oproti aplikaci v C/C++ je ten, že zprasená aplikace chcípe na segfault. Pokud je to jednou týdně tak je to ještě fajn (a pokračuje se podle scénáře výše), ale pokud každých 10 minut tak je to konečná. Musí se to přepsat. Projekt není dokončen (rozhodně ne včas), zákazník neplatí (a naopak má nárok na slevu), prémie nejsou dolů a budou i padat hlavy. V managementu (tam to hodně záleží na politikaření) a možná i mezi programátory. Tam to ale záleží zda seženete lepší. Pravdou je, že je to trochu off-topic: python je v principu stejně vhodný pro enterprise jako Java či .NET, možná někdy i vhodnější. IMHO by se velmi dobře uchytil, kdyby někdy nastartovala kladná zpětná vazba (tj. bylo hodně pythonistů zajímajících se o korporátní praxi). PS: Z vlastní praxe samozřejmě nemám dostatečný vzorek abych mohl generalizovat, ale informace z doslechu mi to jen potvrzují. A kromě toho, povyšování vlastních zážitků na obecně platné pravdy je na tomto fóru standardní praxí
Prostě se kód hodí někomu trochu schopnějšímu a ten do termínu nějak zafixuje ty nejhorší problémy a doplní pár ohejbáků a rovnáků na ohejbáky.
Takže se mnou vlastně souhlasíš Vývoj v Javě je efektivní a funguje – cílem totiž je, vejít se do termínů a rozpočtu a dodat aplikaci, která dělá to, co bylo v zadání. Jestliže tohoto cíle jde v Javě dosáhnout1, tak Java prostě je vhodný jazyk.2
Rozdíl oproti aplikaci v C/C++ je ten, že zprasená aplikace chcípe na segfault.
Javovská aplikace zase může padat na NullPointerException
, nebo třeba čtení indexu mimo rozsah pole, nebo neúspěšné přetypování… ale většinou bude snazší (a tím pádem levnější) takovou chybu nalézt3 a opravit.
Pravdou je, že je to trochu off-topic: python je v principu stejně vhodný pro enterprise
V jedné firmě jsme měli jak Javu, tak C++, vyvíjely to různé týmy a úspěšně fungovalo oboje – myslím, že oboje jsou vhodné jazyky/platformy. Ale o tom Pythonu mám dost pochybnosti.
V Pythonu se neproklikáš skrz zdrojáky, kam potřebuješ, hůř se zjišťuje, co to vlastně dělá a kde bys měl provést opravu/úpravu. Trávit každé odpoledne v debuggeru tě brzo přestane bavit a jdeš se radši zeptat původního autora aplikace4. Průšvih je, když ten člověk pak odejde a tobě zbude jen hromada dynamického kódu, který kdesi uvnitř dělá něco špatně. To se fakt radši budu hrabat v Javě po Indech nebo v C/C++.
[1] a dokonce s větší pravděpodobností než v mnohých jiných jazycích
[2] navzdory tomu, že někdo může považovat Javu za příliš ukecanou nebo omezenou
[3] už z výpisu chyby vidíš třídu, metodu a řádek, kde k ní došlo a odkud se to volalo
[4] tzn. budou nad tím zabíjet čas dva lidi, které firma platí, a toho druhého budeš brzdit v jeho současné práci
V Pythonu se neproklikáš skrz zdrojáky, kam potřebuješProč by ne?
hůř se zjišťuje, co to vlastně děláTo je imho nesmysl.
Trávit každé odpoledne v debuggeru tě brzo přestane bavitOno je dobré vzpomenout, že python debugger (pdb) je REPL. Z mé zkušenosti plyne, že najít tam bug je podstatně jednodušší a zabere to obvykle méně času.
V Pythonu se neproklikáš skrz zdrojáky, kam potřebuješ, hůř se zjišťuje, co to vlastně dělá…Vidíš, já bych řekl že je to přesně naopak. V pytohnu když nějakej kód něco dělá, tak je napsanej tak aby to dělal, a je to vidět protože nic jiného tam prostě není. Protože "simple is better then complex". V Javě to bude obložené tunami zbytečné syntaxe a obestavěně vrstvami zbytečné abstrakce které nejsou k tomu aby program něco dělal, ale jen uspokojují nějakou buzeraci stran kompileru nebo něčí představu o "jediném správném programování". Java je v tomhle možná lepší než C++ páčž jsou tyhle představy aspoň nějak jednotný, ale těžko mě přesvědčíš že promyšlená a zdokumentovaná zbytečnost je přehlednější než žádná zbytečnost
V pytohnu když nějakej kód něco dělá, tak je napsanej tak aby to dělal, a je to vidět protože nic jiného tam prostě není.
To už se bavíš o úspornosti na úrovni jednotlivých řádků, konstrukcí – tedy na té mikroúrovni, která není až tak důležitá. Důležité (a to, o čem jsem psal) totiž je najít to místo (třeba dvacet řádků), kde máš hledat – a v tom ti dynamičnost jazyka hází klacky pod nohy. V Javě může tím místem být třeba 25 řádků místo 20, ale vtip je v tom, že toto místo najdeš mnohem snáze a spolehlivěji.
simple is better then complex
Vtipný překlep Docela často se setkávám s tím, že někdo přijde s nápadem: „jednodušší je lepší“ – a následně, ve výsledku je to spíš složitější.
V Javě to bude obložené tunami zbytečné syntaxe a obestavěně vrstvami zbytečné abstrakce které nejsou k tomu aby program něco dělal
Ta abstrakce není jen tak pro nic za nic, dává ti větší flexibilitu, umožňuje např. měnit implementace různých věcí, aniž bys musel zasahovat do zbytku programu. Často ho ani nemusíš překompilovávat a jde to udělat na úrovni konfigurace.
Na Javě se často kritizují továrny (factory – návrhový vzor). Tady je dobré si uvědomit, že jde vlastně o funkcionální programování. Továrna je ve své podstatě funkce, která generuje další funkce nebo objekty. Továrnu/funkce můžeš odněkud dostat a použít ji, aniž bys musel řešit, kde se vzala a co je uvnitř – prostě pracuješ s předem definovaným rozhraním a víc tě nemusí zajímat.
které nejsou k tomu aby program něco dělal, ale jen uspokojují nějakou buzeraci stran kompileru nebo něčí představu o "jediném správném programování".
Hned vedle máš pěkný příklad – Python vs. XSLT. V Pythonu potřebuješ 17 řádků (+2 na konci) na balastní kód, který nic pořádného nedělá, nesouvisí s byznys logikou dané úlohy. Zatímco v XSLT máš v 17 řádcích celý program. V Pythonu je celý program na 38 řádků.
Nemám rád porovnávání počtu řádků kódu, nepovažuji to za úplně důležitý ukazatel. Ještě zajímavější je ten obsah. V XSLT máme 5 řádků ze 17, které představují šablonu výsledného dokumentu – tato šablona odpovídá výsledku jak strukturou (wallet/folder/password
), tak formou (XML) a je tedy dobře čitelná a srozumitelná. Další 4 řádky ze 17 představují FOR cykly, jejichž přítomnost je daná zadáním (snažil jsem se co nejvíc napodobit tu pythoní implementaci – jinak to šlo taky udělat jen přes šablony, bez FOR cyklů). Další 2 řádky jsou prázdné. A jen 4 řádky se dají označit jako hlavička/zápatí, jakýsi nezbytný a ne příliš užitečný kód. Nepotřebuješ žádné pomocné proměnné (a neustále se koukat nahoru do kódu, co v nich vlastně je uložené) a nepotřebuješ znát žádné zvláštní metody a konstruktory, protože šablona a výsledek k sobě mají velmi blízko, vidíš to na první pohled.
Pokud máš problém pochopit fungování nějakýho pajtního kódu a není to něco opravdu složitýho (v jakémkoliv jazykce), tak vsadím koláč proti psímu sucharu že chyba není v pajtnu ale v javovských idiomech a konstrukcích který tam někdo ze zvyku zatáhl.
Tak jsi právě prohrál koláč. Ten kód, o kterém jsem mluvil, psal člověk, který nesnášel Javu, přišla mu příliš ukecaná, staromódní a těžkotonážní, a byl nadšeným propagátorem Pythonu.
Dělat ze všeho za každou cenu objekty, singletony, zbytečný strukturování
Jako že bychom místo objektů používali radši seznamy a mapy a textové klíče? No tak to by bylo ještě lepší! V tom už by člověk nenašel vůbec nic, byla by to ještě větší hromada hnoje, chatrná skládačka, která na sebe brzo přestane pasovat (textové klíče se rozpadnou, na každé straně programu budou jiné, a těžko se to zjistí1) a v tom se člověk neprokliká už vůbec nikam. Můžeš leda tak grepo
vat zdrojáky a ručně zkoumat, co je ten správný textový klíč, co je náhodná shoda a co naopak nenalezená shoda (např. dynamicky skládaný klíč z několika částí, který grep
em nenajdeš).
pokud stejná funkčnost není v pajtnu desetkrát míň kódu než v C++, tak je něco špatně.
Tohle není dané jazykem, ale knihovnami. Jestliže má někdo tento pocit, tak je to iluze způsobená tím, že pro Python má k dispozici lepší knihovny než pro C. Pokud budeš mít podobně vysokoúrovňové knihovny pro Python, Javu, C, C++, tak není důvod, aby se délka programu zásadně lišila – nějaké odchylky tam budou, ale rozhodně ne desetinásobné – spíš tak v jednotkách procent nebo třeba 10 %.
[1] tady asi někdo namítne, že se mají psát unit testy – v tom případě si k počtu řádků programu přičti ještě počet řádků testů, které musíš napsat jen pro kontrolu toho, co ti v jiných jazycích ohlídá zadarmo kompilátor – a už to najednou tak úsporně nevypadá, řádků kódu je v součtu víc
V Javě může tím místem být třeba 25 řádků místo 20, ale vtip je v tom, že toto místo najdeš mnohem snáze a spolehlivěji.No tak to bych teda chtěl vidět nějaké podložení tohoto výroku. V Javě osobně nenajdu věci o nic snáz než v Pythonu, možná i hůř, vzhledem k oblíbenému zvyku Javistů zaobalovat objekty do jiných objektů a ty do dalších objektů atd., používat všelijaké
AbstractFactoryVisitorProviderAdapter
a podobné srandy. Stalo se mi asi u dvou nebo třech Java projektů, že jsem narazil na celé adresáře plné nějakého boilerplate kódu / balastu a vlastní logika aplikace byla zahrabaná kdesi mezitím nebo taky úplně jinde...
To je spíš otázka konkrétního programátora než jazyka. Samozřejmě, že nepotřebného balastního kódu je škoda. Pro Javu jsou i nástroje a metriky, které ti odhalí mrtvý nebo nedosažitelný kód, nebo třeba upozorní přílišnou složitost.
Ale jde o to, že i navzdory těmto neduhům se k té implementaci nakonec v IDE proklikáš, buď přímo přes metody nebo si zobrazíš seznam tříd implementujících dané rozhraní nebo potomků. Je to jedno kliknutí a spolehlivě je najdeš. Kdežto u dynamického jazyka je to prostě horší. Moje osobní zkušenost je taková, že je lepší se jít zeptat původního autora (pokud je tedy k dispozici), který si pamatuje, kam danou funkcionalitu napsal, než se to pokoušet hledat sám (on by to taky v cizím kódu jen tak nenašel). Jedna část toho projektu měla cca 20 tisíc řádek a druhá cca 80, to prostě není jako když si lidi píší skripty na jednu obrazovku a podle toho soudí. Naštěstí většinou stačilo hledat v té menší části, ale ani tak to nebylo jednoduché.
Kdežto u dynamického jazyka je to prostě horší. Moje osobní zkušenost je taková...Jen aby bylo jasno - týká se tvoje osobní zkušenost pythonu, nebo čeho vlastně?
jj, byl to Python. A když to srovnám s programem v Javě (který měl tak 6× víc řádků), tak v tom se dalo zorientovat a vyznat lépe.
Linux má 50× víc řádků než jEdit → programy v C jsou 50× větší než programy v Javě!
Ne, byly to různé aplikace, ale chtěl jsem tím říct, že v javovském programu se stejným (nebo i vyšším) počtem řádků se IMHO dá orientovat lépe. Já vím, že to nejde úplně zobecňovat, ale tohle je prostě můj aktuální dojem a hodnocení Java vs. Python. Co se týče kvality programátorů, tak ani ten javovský kód nepsali nějací špičkoví programátoři a kvalita byla dost „různorodá“.
Ale jde o to, že i navzdory těmto neduhům se k té implementaci nakonec v IDE proklikáš, buď přímo přes metody nebo si zobrazíš seznam tříd implementujících dané rozhraní nebo potomků.Detektivní práce to ale bude tak jako tak. Osobně když potřebuju něco hledat v nějakém projektu (třeba se jedná o desetitisíce řádek), tak ačkoli to třeba je jazyk proklikatelný v IDE (C/C++/Java/...), tak často stejně nakonec skončím u grepu et al. + IDE v podstatě jen pro zobrazení a navigaci
Netbeans mají funkci „Find in projects“, což je taková kombinace grep
u a find
u s GUI, řekneš, v jakých souborech hledat (přípony, regulární výraz) a co hledat (text, regulární výraz…) a hlavně se pak z výsledků proklikáš na zdrojáky, jsi pořád v IDE a nemusíš si kopírovat nebo opisovat názvy souborů z konsole. Ale moc to nepoužívám – většinou se totiž dá dobře skrz zdrojáky navigovat pomocí funkcí, které tomu zdrojáku rozumí, chápou syntaxi a neberou ho jen jako text.
...a v tom ti dynamičnost jazyka hází klacky pod nohy. V Javě může tím místem být třeba 25 řádků místo 20, ale vtip je v tom, že toto místo najdeš mnohem snáze a spolehlivěji.Mozna hazi. Ale v Jave tech radku nebude 25 ale 200 v peti ruznych objektech.
To cituju klasika. Cele je to trochu delsi:simple is better then complexVtipný překlepDocela často se setkávám s tím, že někdo přijde s nápadem: „jednodušší je lepší“ – a následně, ve výsledku je to spíš složitější.
Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!Cim dele se prganim zivim, tim vic zjistuju ze jsou to zlata slova.
Na Javě se často kritizují továrny (factory – návrhový vzor). Tady je dobré si uvědomit, že jde vlastně o funkcionální programování. Továrna je ve své podstatě funkce, která generuje další funkce nebo objekty. Továrnu/funkce můžeš odněkud dostat a použít ji, aniž bys musel řešit, kde se vzala a co je uvnitř – prostě pracuješ s předem definovaným rozhraním a víc tě nemusí zajímat.Ja vim co je fabricka metoda. V pythonu je pouzivam bezne, jen pri tom nemusim psat tuny zbytecneho kodu jen abych takzvane objektovemu jazyku vysvetlil ze funkce je take objekt. Vetsinou staci jedno rovnitko. Ostatne ted kdyz se java naucila lambdy a uzavery tak se snad pohnou ledy.
Hned vedle máš pěkný příklad – Python vs. XSLT.Jo to je moc pekny priklad. Jenom jsi nejak zapomel zminit kolik kodu by to bylo v jave. Jinak to nic nerika - ja jsem uplne stejnym zpusobem v predchozi praci vymenil desitky radku javy za jeden (slovy: "1") radek awku, ale nevyvozuju z toho vic nez ze pro dane zadani je awk uzitecny. Za stejnou cenu jako XSLT - ze je nepouzitelny pro cokoliv jineho.
Klidne, ale nejdriv ukaz ten kod.Pokud máš problém pochopit fungování nějakýho pajtního kódu a není to něco opravdu složitýho (v jakémkoliv jazykce), tak vsadím koláč proti psímu sucharu že chyba není v pajtnu ale v javovských idiomech a konstrukcích který tam někdo ze zvyku zatáhl.Tak jsi právě prohrál koláč. Ten kód, o kterém jsem mluvil, psal člověk, který nesnášel Javu, přišla mu příliš ukecaná, staromódní a těžkotonážní, a byl nadšeným propagátorem Pythonu.
Jako ze objekt reprezentuje nejakou skutecno entitu nebo funkcnost, ne jen magickou formulku kterou musis dokola opisovat aby te kompiler nezjebal. Ale tohle ti asi nevysvetlim, to neni v jazyku ale v hlave. Pohrdave se vyjadrujes o seznamech a mapach, pritom to jsou perfektni objekty. A to cemu rikas objekt je v pythonu zase jenom mapa. Pritom se to chova daleko vic objektove nez Java, kde jsou objekty v podstate jen tecky ve jmenech. Schvalne, jak bys teda v pythonu napsal singleton?Dělat ze všeho za každou cenu objekty, singletony, zbytečný strukturováníJako že bychom místo objektů používali radši seznamy a mapy a textové klíče?
Ušetří ti to práci.Nevšiml jsem si, spíš mám pocit, že ojebávání programu syntaktickými hříčkami mi práci dříve či později přidělá.
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.