#37 Kit
No musím přiznat, že to dává smysl. Díky za to
Příspěvky odeslané z IP adresy 212.158.129.–
#33 gcx11
Tak domů se jen tak nedostanu - v rychlosti jsem to splácal do toho co posílal Kit, snad to není v rozporu tím co jsem spatlal doma a bude to dávat smysl. Nějaké prohřešky nesouvisející s dotazem mi pls promiňte - nejsem v Pythonu zběhlí a psal jsem to v bombách
class MyRubylikeThing(object):
def __init__(self, server):
self.server = server
def __getattr__(self, name):
def _missing(*args, **kwargs):
if hasattr(self.server, name):
getattr(self.server, name)(*args, **kwargs)
else:
print("Unknown message: " + name)
return _missing
class MyServer(object):
def __init__(self, text):
self.t = text
@property
def prop(self):
return self._prop
@prop.setter
def prop(self, value):
self._prop = value
def hello(self):
print(str(self.t))
def cau(self, text):
print(str(text))
#vlastní typ
s = MyServer("hello boy")
r = MyRubylikeThing(s)
r.UnknownMsg() #Test return Unknown message
r.hello() # return hello boy
r.cau("kamo") #return kamo
#-----
#vestavěný typ str
s = "text"
r = MyRubylikeThing(s)
print(r.capitalize()) #return None
#vestavěný typ int
s = 58
r = MyRubylikeThing(s)
print(r.bit_length()) #return None
#
s = MyServer("nejakyText")
s.prop = "DatovyAtribut"
print(str(s.prop)) #return DatovyAtribut
r = MyRubylikeThing(s)
print(str(r.prop)) #Nerozumím :)
#35 Kit
Už jsem tě konečně pochopil. Pokud to návrh dovoluje je určitě lepší předat hodnoty už v "konstruktoru" nebo chceš li po zavolání __init__. No, nejsem si jistý jestli je to přímo princip OOP, ikdyž to může být vnímáno jako porušení zapouzdření. Ok. Každopádně je to nyní nepodstatné. Spíše to vzniklo jako tvoje rekace na dotaz ohledně přesměrování zpráv viz #4 a #5
Ještě jednou díky
#25 Kit
Ukázku až kam jsem se dostal mám doma, ale je to skoro ono. Akorát jsem v _missing volám fce hasattr, kdyby objekt na kterého chci zprávu přesměrovat taky nerozumněl a getattr jako alternativu k obj.send, ale ta mi u vestavěných typů vrací none.
Vyzkouším teď. Díky
#16 gcx11
Ještě k těm vestavěným typům a rozšíření. Tady samozřejmě nepomůže nic, dict jsou jen pro čtení. To je škoda mimochodem. Rozšíření tříd může být vhodnější alternativa k dědění. Na co dědit, když můžu existující typ rozšířit a to i dokonce již existující instance. Opět v Ruby není problém. Škoda.
Ještě jednou díky
#16 gcx11
Ahoj gcx11, děkuji ti za reakci,
nepotřebuji rozšířit třídu za běhu, to zvládám pomocí monkey-patching. Jde mi opravdu jen o přesměrování zpráv - to za složitý hack nepovažuji, protože je to běžně užívaná technika a to zejména u kachnotypích jazyků. Nechci sem pořád zatahovat Ruby, ale tam se to používá běžně. Zkusím vysvětlit:
Jak v jazycích staticky i dynamicky typovaných se občas využívá vkládání objektů, tj něco takového:
class Obj():
server = Nejakytyp()
...
Může to být v __init__, ale to je nepodstatné. Ve třídě/typu se vytváří instance dalšího objektu (tzv. vkládaného), na kterého se - za horizontem zapouzdření - přesměrují "služby" objektu (Obj()). Já ale nechci implementovat všechny "služby" ručně a přesměrovávat každou zprávu zvlášť - chci, aby se za horizontem zapouzdření o to přesměrování zpráv postaral objekt, který (např v ukázce v Ruby předávám pomocí vlastnosti server) ve kterém jsou služby implementovány. A samozřejmě postup v úkázce, kromě zbytečné dřiny pro programátora není úplně zrovna elegantní řešení, ale to je nepodstatné, jde jen o vysvětlení podstatného.
Můj problém je vlastně takový, že potřebuji alternativu k rubiovskému obj.send, která umí dynamicky sestavit obj.zprava() pro vestavěný a vlastní typ. Jinak řečeno: umí nepřímo zaslat zprávu jinému objektu. Díky, ale nestojím o jiné postupy a návrhy. Jde to nějak v Pythonu nebo ne tak, abych to mohl využít pro přesměrování zpráv? To je moje otázka.
Přesměrování jsem si nevymyslel sám, ale jiný uznávaní odborníci, který tento princip za porušení OOP principů nepovažují, spíše naopak - je v souladu s myšlenkou předávání zpráv - tak jako v reálném životě se může objekt rozhodnout, jak na zprávu zareaguje (přijmout a vykonat službu, odmítnout, nebo předat). Vše se děje za horizontem zapouzdření, programátor ani nemusí vědět, že objekt zprávu předal jinému objektu, který se o služby postará. Nerozumím té argumentaci o porušení zapouzření - kde proboha? Valstně jsou to z mé strany spíše parafráze - není to z mé hlavy.
Díky za ukázky, určitě je doma prostuduji a uvidím zda by mi v tomto ohledu mohli pomoci.
#10 Kit
U dědičnosti - zejména ve větším systému - vzniká efekt joja - dá se dohledat na netu. Nebo další problémy jako "fragile base class" apod. Vzniká nepřehledný systém, přitom - většinou - existují vhodnější alternativy. Dědění je zbytečně nadužívané. Zejména v dynamicky typovaném systému existují vhodné alternativy. Ale to je vlastně jedno - teď nejde o dědění.
Původní zadání s příkladem souvisi, jde mi o alternativu k rubiovskému obj.send, funkce pythonu getattr zdá se nepracuje s vestavěnými typy. V Ruby je to snadné, pokud se budu držet ukázky co jsem poslal (ta už je snad jasná), použití by vypadalo takto.
s = RubyObject.new()
s.server = "Text"
s.lenght # vrátí 4
#nebo
s.server= VlastniTyp.new()
s.zprava
#jak toto přesměrování implementovat v Pythonu?:
s = PyObj()
s.server = "{0}"
s.format("Text") # vrací none, proč?
#nebo (toto dokáži)
s.server = VlastniTyp()
s.zprava
Tady fakt nevidím problém se zapouzdřením.
Víc už ze sebe nevymáčknu - vzdávám to tady. Měj se hezky a díky za reakce
#8 Kit
S tím zapouzdřením to samozřejmě - v tomto případě - není pravda. Pouze zasílám objektu zprávu, pokud objekt zprávě nerozumí předá ho jinému objektu - serveru. Pořád s objektem pracuji jako s černou skříňkou. Programátor ani nemusí vědět, že objekt zprávu předal. Synu oprav motor - neumím - předám otcovi. Vše se děje za horizontem zapouzdření. Kde se pokouším z venku pracovat s atributy objektu? V ukázce, kterou jsem poslal je evidentní, že využiji jen API objektu (vlastnost server), zbytek se děje v rámci zapouzdření.
attr_accessor :server v ruby vytvoří vlastnost server pro čtení a zápis. method_missing se zavolá vždy, pokud objekt zaslané zprávě nerozumí. Metoda/zpráva send odešle objektu (server) zprávu.
Dědičnosti se snažím vyhnout vždy, když je to možné. Např. pomocí rozšíření tříd, delegátem a třeba právě přesměrováním zpráv. Důvodů proč se vyhnout dědění a využít raději alternativních postupů je celá řada. To poslední co potřebuji je další potomek, nepotřebuji ho.
Evidentně máme každý jiný názor na OOP, ale pokud vypustíme, podle tebe lepší možnosti, a soustředíme se na podstatu dotaz - uměl bys pls poradit?
Díky moc za reakce
#6 Kit
A jakou zásadu podle tebe porušuji v rámci zapouzdření? Přesměrování zpráv právě respektuje objekt jako černou skříňku. Když právě dodržím zapozdření tak ani nemusím vědět, že objekt, který zprávě nerozuměl jí předal jinému objektu. Co tam přesně vidíš za problém se zapouzdřením?
Můžeš mi tedy, prosím, poslat ukázku, jak lze podle tebe implementovat přesměrování zprávy jakémukoliv (vestavěnému i vlastnímu) typu, který je předán pomocí vlastnosti? Teda pokud ti to ego dovolí.
Princip v Ruby:
class RubyObject
attr_accessor :server
def method_missing(id, *args, &block)
return @server.send(id, *args, &block)
end
end
Jak tedy v Pythonu vytvořím alternativu k obj.send bez getattr funkce tak, abych dokázal dynamicky sestavit obj.zprava() pro vestavěný a vlastní typ? Naformátováním stringu v objektu? - Nechápu, jak přesně pls?
Díky
Dobrý den,
jakým způsobem se v Pythonu provádí Extension Methods?
Tj., chci za běhu programu přidat do existujícího typu (class) novou metodu. Nová metoda pak bude dále v programu dostupná.
Co z následujících dvou způsobů můžu považovat za Extension Methods? Připadně existuje jiná možnost?:
Díky
#1.
class Auto(object):
def troubeni(self):
print("tutu")
class Auto(Auto):
def couvani(self):
print("couvam")
vw = Auto()
vw.troubeni()
vw.couvani()
print("----------")
#2
class Lednice(object):
def mrazeni(self):
print("mrazim")
def chlazeni():
print("chladim")
ld = Lednice()
ld.mrazeni()
ld.chlazeni=chlazeni()