Ad házení výjimek, jakej je rozdíl mezi
try:
a=b(a=1,b=2,c=3);
catch:
a
try:
a=b();
a.seta(1);
a.setb(1);
a.setc(1);
catch:
Jeden rozdíl tam přesně vidím - i když to spadne na nějakou obecnou výjimku, v případě 2) vidím, která vlastnost to způsobila, aniž bych musel lízt do definice objektu.
Další výhoda přístupu 2 je při modifikacích kódu - když budu mergovat patche, tak při přístupu 2 vidím hned a daleko lépe, co daný patch změnil. To, že každá řádka má dělat pokud možno jen jednu věc není pravidlo zbytečné (byť samozřejmě jako všechny ostatní velmi často odůvodnitelně porušitelné).
----
Objekty uživatelskýho rozhraní zpravidla maj hromadu parametrů, ale pokud člověk programuje rozumně, tak např. používá themes, takže většina těch parametrů je danejch... Stejnětak font člověk málokdy vytváří "adhoc". Samozřejmě, existují případy, kdy je třeba tydle objekty vytvářet - ale to jsou poměrně řídké výjimky.
----
Co se týče funkcí - tak samozřejmě existují funkce, kde je více argumentů opodstatněných. Ale příliš časté nejsou. Co se týče např. toho popen, tak tam např. místo předání pole deskriptorů (což by umožnilo dát subprocesu víc než jen standardní tři vstupy/výstupy) se dává každej v spešl argumentu. A navíc je to implementace "děravá", viz varování u atributů vzniklého objektu.
Dál jsou tam flagové proměnné - a to jen jiný zápis bitového pole, který pokládám za o něco vhodnější (líp se uchovává stav volání, loguje, kvůli přidání přepínače se nemusí přidávat argument fce...). Pokud nesouhlasíš, tak prostě tydle argumenty pro účely pravidla počítej jako jeden.
No a pak jsou tam dva argumenty, svázané s implementací té funkce na jednom konkrétním OS, což je poměrně úlet (až se python rozšíří na deset OS, tak tam bude těch proměnejch dvacet??).
A je to kontruktor (takže opět by to šlo rozepsat do následných volání).
No a naposled ta třída dělá x věcí (např. hraní si s deskriptorama), pro který by asi bylo výhodný udělat spešl třídu, protože hrát si s deskriptorama je potřeba i jinde a tak je užitečný, aby se to dělo jednotnym způsobem.
Takže design tý třídy za nějak extra dobrej nepovažuju.
Stejně tak psycopg2.connect() má v podstatě jeden argument - buďto řetězec, nebo struktura či asociativní pole parametrů pro spojení. Zbytek je syntax sugar pythonu, umožněná hlavně konstrukcí **pole (jinak bych za takovoudle syntaxi "vraždil", protože si ty parametry člověk většinou schovává někde v konfiguraci v nějaké struktuře a rozbalovat je ručně je blbina).
Samozřejmě, tři (já ani nevím, jestli v originále pravidla je tři, čtyři nebo kolik, prostě "málo") je velmi striktní číslo a najdou se příklady, kdy je rozumné mít argumentů víc. Jako každé z pravidel to samozřejmě není pravidlo striktní, ale ukazuje na možné chyby v designu aplikace a když si to sám před sebou obhájím, tak ho klidně poruším. To ale nic
nemění na tom, že má velmi často pravdu....
To, jak python zachází s argumentama je úžasný, asi nejlíp z jazyků, co znám (automatické rozbalování polí, pojmenované parametry). Občas se mi ale zdá, že to vede k přílišnému "zplošťování funkcí"
----
Ondra: to je vnořená, ne anonymní třída. To, že něco pojmenuješ anonymní, tak tím ještě anonymní třídu neuděláš :-). Proto jsem psal také, že to jde nejhůř (syntax je rozvleklá, vyžaduje zbytečnej identifikátor a nedá se napsat "inplace", což vše ztěžuje čitelnost programu) a ne že to nejde.
S readonly objejkty máš samozřejmě pravdu, ale ty málokdy bývají příliš komplexní (a nebo jdou rozložit na agregaci menších komplexních objektů).