<br><font size=2 face="sans-serif">ani ja v tom priklade nevidim uplatnenie
pre staticke metody</font>
<br>
<br><font size=2><tt>>Poznámka: kromě staticmethod() a příslušného<br>
>dekorátoru existuje i classmethod(), ke které <br>
>jsme se zatím nedostali.</tt></font>
<br>
<br><font size=2><tt>Tak k tomu podme teraz:-)</tt></font>
<br><font size=2><tt>Aky je teda vlastne rozdiel medzi classmethod a staticmethod.
Vzdy som si myslel, ze staticka metoda/premenna je synonymum pre metodu/premennu
triedy. Alebo nie?</tt></font>
<br>
<br>
<br>
<br>
<br>
<table width=100%>
<tr valign=top>
<td width=40%><font size=1 face="sans-serif"><b>"Petr Prikryl"
<PrikrylP@skil.cz></b> </font>
<br><font size=1 face="sans-serif">Sent by: python-bounces@py.cz</font>
<p><font size=1 face="sans-serif">08.11.2006 15:28</font>
<table border>
<tr valign=top>
<td bgcolor=white>
<div align=center><font size=1 face="sans-serif">Please respond to<br>
Konference PyCZ <python@py.cz></font></div></table>
<br>
<td width=59%>
<table width=100%>
<tr>
<td>
<div align=right><font size=1 face="sans-serif">To</font></div>
<td valign=top><font size=1 face="sans-serif">"Konference PyCZ"
<python@py.cz></font>
<tr>
<td>
<div align=right><font size=1 face="sans-serif">cc</font></div>
<td valign=top>
<tr>
<td>
<div align=right><font size=1 face="sans-serif">Subject</font></div>
<td valign=top><font size=1 face="sans-serif">Re: [python] Statické metody
v Pythonu</font></table>
<br>
<table>
<tr valign=top>
<td>
<td></table>
<br></table>
<br>
<br>
<br><font size=2><tt>Díval jsem se na to znovu a beru zpět to, <br>
že si myslím, že tohle využití vypadá zajímavě.<br>
<br>
<br>
superman<br>
> [...]Protože v předkovi uhel se počítá s tím, že v metodě <br>
> __add__ se přes self předává jen jeden argument, najednou <br>
> si v potomku začne stěžovat na dva. Python má v tomhle <br>
> asi nepořádek a asi nesnáší takové šťoury jako jsem já. <br>
> Takže závěr nikdy nezkoušejte předefinovat statickou <br>
> metodu nestatickou, protože Python si s tím neví <br>
> rady a začne hlásit chyby i tam, kde by to v jiných <br>
> jazycích bylo v pořádku. Never is perfect :-)))<br>
> [myšleno asi Nobody is perfect -- Někdo to rád horké]<br>
<br>
> class uhel:<br>
> <br>
> @staticmethod<br>
> def static(a):<br>
> print "trida1.static(): ",
a<br>
> <br>
> def method(self):<br>
> self.static(1)<br>
> <br>
> class zemepisny_uhel(uhel):<br>
> <br>
> #@staticmethod<br>
> def static(a):<br>
> print "trida2.static(): ",
a<br>
> <br>
> a = uhel()<br>
> a.method()<br>
> <br>
> b = zemepisny_uhel()<br>
> b.method()<br>
> <br>
> trida1.static(): 1<br>
> Traceback (most recent call last):<br>
> File "C:\home\astrol\test.py", line 25, in
?<br>
> b.method()<br>
> File "C:\home\astrol\test.py", line 10, in
method<br>
> self.static(1)<br>
> TypeError: static() takes exactly 1 argument (2 given)<br>
> <br>
> Závěr: Python se chová tak, jako kdyby definici třídy znovu <br>
> překládal do definice potomka. Zápis self.static přeloží <br>
> v uhel.method jako volání statické metody s jedním parametrem, <br>
> zatímco v zemepisny_uhel jako volání normální metody se dvěma <br>
> parametry. Řekl bych, že tato feature je dost error prone, <br>
> a že vlastnost "zapouzdření" dostává pěkně na zadek.<br>
<br>
Já na tom nevidím nic divného. V části <br>
<br>
> class zemepisny_uhel(uhel):<br>
> #@staticmethod<br>
> def static(a):<br>
> print "trida2.static(): ",
a<br>
<br>
je dekorátor zapoznámkovaný, takže je to stejné, jako kdybych<br>
napsal <br>
<br>
class zemepisny_uhel(uhel):<br>
def static(a):<br>
print "trida2.static(): ",
a<br>
<br>
Což je stejné jako<br>
<br>
class zemepisny_uhel(uhel):<br>
def static(self):<br>
print "trida2.static(): ",
self<br>
<br>
Jenom jsi porušil konvenci, že první argument metody se má<br>
pojmenovat self. No a druhý argument tam není. Myslím,<br>
že interpret Pythonu v tom docela jasno MÁ ;o)<br>
<br>
A ještě k tomu použití statické metody. Možná máš znalosti<br>
C++, kde se zápis typu <br>
<br>
zem_uhel + "30N54" <br>
<br>
typicky dosahuje přetížením operátoru + a typicky se<br>
implementuje tak, že se na místě druhého argumentu očekává<br>
konstantní reference a třídu zemepisny_uhel. Jenže <br>
u třídy zemepisny_uhel by se v takovém případě typicky <br>
definoval konstruktor, který bere odkaz na konstantní string<br>
a může se tam tedy dosadit i literál. Překladač pak automaticky<br>
udělá tohle:<br>
<br>
zem_uhel + zemepisny_uhel("30N54")<br>
<br>
tj. nejdříve zkonstruuje pomocný objekt pro druhý argument.<br>
Dále se to dá rozepsat jako<br>
<br>
zem_uhel.operator+(zemepisny_uhel(("30N54")))<br>
<br>
Python ale implicitně podobný konstruktor nezavolá. Podle <br>
mého by tedy měla být třída uhel vytvořena tak, aby její<br>
složka __radians jednoduše obsahovala platnou hodnotu, nebo<br>
by se měla definovat metoda, která hodnotu v radiánech<br>
vrací. Metoda __add__ by jako argument měla brát instanci<br>
třídy uhel a udělat jednoduše<br>
<br>
class uhel:<br>
def __init__(self, radian):<br>
self.__rad = radian<br>
<br>
def __add__(self, u):<br>
return self.__rad + u.__rad<br>
<br>
def __str__(self):<br>
return str(self.__rad)<br>
<br>
<br>
u1 = uhel(1.0)<br>
u2 = uhel(2.0)<br>
<br>
print u1<br>
print u2<br>
<br>
u3 = u1 + u2<br>
u4 = u1 + uhel(3.0)<br>
<br>
print u3<br>
print u4<br>
<br>
Třída zemepisny_uhel by byla odvozená v tom smyslu, <br>
že by měla jinou implementaci __init__(), ve které<br>
by se mohly rozpoznávat různé formy předaného argumentu.<br>
Pak by to mohlo vypadat takhle:<br>
<br>
class uhel:<br>
def __init__(self, radian):<br>
self.__rad = radian<br>
<br>
def __add__(self, u):<br>
return self.__rad + u.__rad<br>
<br>
def __str__(self):<br>
return str(self.__rad)<br>
<br>
<br>
class zemepisny_uhel(uhel):<br>
def __init__(self, s):<br>
uhel.__init__(self, float(s))<br>
<br>
u1 = uhel(1.0)<br>
u2 = uhel(2.0)<br>
<br>
print u1<br>
print u2<br>
<br>
u3 = u1 + u2<br>
u4 = u1 + uhel(3.0)<br>
<br>
print u3<br>
print u4<br>
<br>
z = zemepisny_uhel('4.0')<br>
<br>
print z<br>
print u1 + z<br>
print z + u2<br>
<br>
Uplatnění pro statické metody jsem v tom příkladu<br>
zatím nenašel. <br>
<br>
Poznámka: kromě staticmethod() a příslušného<br>
dekorátoru existuje i classmethod(), ke které <br>
jsme se zatím nedostali.<br>
<br>
pepr<br>
_______________________________________________<br>
Python mailing list<br>
Python@py.cz<br>
http://www.py.cz/mailman/listinfo/python<br>
</tt></font>
<br><font size=2 face="sans-serif"><br>
Mgr. Ing. Roman MIKLÓŠ <br>
Prvá stavebná sporiteľňa a.s. <br>
Bajkalská 30, P. O. Box 48 <br>
829 48 Bratislava 25 <br>
Tel.: +421/ 2 / 582 31 174 <br>
Fax: +421/ 2 / 582 31 109 <br>
</font>