<br><font size=2 face="sans-serif">ani ja v tom priklade nevidim uplatnenie
pre staticke metody</font>
<br>
<br><font size=2><tt>&gt;Poznámka: kromě staticmethod() a příslušného<br>
&gt;dekorátoru existuje i classmethod(), ke které <br>
&gt;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>&quot;Petr Prikryl&quot;
&lt;PrikrylP@skil.cz&gt;</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 &lt;python@py.cz&gt;</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">&quot;Konference PyCZ&quot;
&lt;python@py.cz&gt;</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>
&gt; [...]Protože v předkovi uhel se počítá s tím, že v metodě <br>
&gt; __add__ se přes self předává jen jeden argument, najednou <br>
&gt; si v potomku začne stěžovat na dva. Python má v tomhle <br>
&gt; asi nepořádek a asi nesnáší takové šťoury jako jsem já. <br>
&gt; Takže závěr nikdy nezkoušejte předefinovat statickou <br>
&gt; metodu nestatickou, protože Python si s tím neví <br>
&gt; rady a začne hlásit chyby i tam, kde by to v jiných <br>
&gt; jazycích bylo v pořádku. Never is perfect :-)))<br>
&gt; [myšleno asi Nobody is perfect -- Někdo to rád horké]<br>
 <br>
&gt; class uhel:<br>
&gt; <br>
&gt; &nbsp; &nbsp; &nbsp;@staticmethod<br>
&gt; &nbsp; &nbsp; &nbsp;def static(a):<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;print &quot;trida1.static(): &quot;,
a<br>
&gt; <br>
&gt; &nbsp; &nbsp; &nbsp;def method(self):<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;self.static(1)<br>
&gt; <br>
&gt; class zemepisny_uhel(uhel):<br>
&gt; <br>
&gt; &nbsp; &nbsp; &nbsp;#@staticmethod<br>
&gt; &nbsp; &nbsp; &nbsp;def static(a):<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;print &quot;trida2.static(): &quot;,
a<br>
&gt; <br>
&gt; a = uhel()<br>
&gt; a.method()<br>
&gt; <br>
&gt; b = zemepisny_uhel()<br>
&gt; b.method()<br>
&gt; <br>
&gt; trida1.static(): &nbsp;1<br>
&gt; Traceback (most recent call last):<br>
&gt; &nbsp; &nbsp;File &quot;C:\home\astrol\test.py&quot;, line 25, in
?<br>
&gt; &nbsp; &nbsp; &nbsp;b.method()<br>
&gt; &nbsp; &nbsp;File &quot;C:\home\astrol\test.py&quot;, line 10, in
method<br>
&gt; &nbsp; &nbsp; &nbsp;self.static(1)<br>
&gt; TypeError: static() takes exactly 1 argument (2 given)<br>
&gt; <br>
&gt; Závěr: Python se chová tak, jako kdyby definici třídy znovu <br>
&gt; překládal do definice potomka. Zápis self.static přeloží <br>
&gt; v uhel.method jako volání statické metody s jedním parametrem, <br>
&gt; zatímco v zemepisny_uhel jako volání normální metody se dvěma <br>
&gt; parametry. Řekl bych, že tato feature je dost error prone, <br>
&gt; a že vlastnost &quot;zapouzdření&quot; dostává pěkně na zadek.<br>
<br>
Já na tom nevidím nic divného. V části <br>
<br>
&gt; class zemepisny_uhel(uhel):<br>
&gt; &nbsp; &nbsp; &nbsp;#@staticmethod<br>
&gt; &nbsp; &nbsp; &nbsp;def static(a):<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;print &quot;trida2.static(): &quot;,
a<br>
<br>
je dekorátor zapoznámkovaný, takže je to stejné, jako kdybych<br>
napsal <br>
<br>
 class zemepisny_uhel(uhel):<br>
 &nbsp; &nbsp; &nbsp;def static(a):<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;print &quot;trida2.static(): &quot;,
a<br>
<br>
Což je stejné jako<br>
<br>
 class zemepisny_uhel(uhel):<br>
 &nbsp; &nbsp; &nbsp;def static(self):<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;print &quot;trida2.static(): &quot;,
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 + &quot;30N54&quot; <br>
<br>
typicky dosahuje přetížením operátoru + &nbsp;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(&quot;30N54&quot;)<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((&quot;30N54&quot;)))<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>
 &nbsp; &nbsp;def __init__(self, radian):<br>
 &nbsp; &nbsp; &nbsp; &nbsp;self.__rad = radian<br>
<br>
 &nbsp; &nbsp;def __add__(self, u):<br>
 &nbsp; &nbsp; &nbsp; &nbsp;return self.__rad + u.__rad<br>
<br>
 &nbsp; &nbsp;def __str__(self):<br>
 &nbsp; &nbsp; &nbsp; &nbsp;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>
 &nbsp; &nbsp;def __init__(self, radian):<br>
 &nbsp; &nbsp; &nbsp; &nbsp;self.__rad = radian<br>
<br>
 &nbsp; &nbsp;def __add__(self, u):<br>
 &nbsp; &nbsp; &nbsp; &nbsp;return self.__rad + u.__rad<br>
<br>
 &nbsp; &nbsp;def __str__(self):<br>
 &nbsp; &nbsp; &nbsp; &nbsp;return str(self.__rad)<br>
<br>
<br>
class zemepisny_uhel(uhel):<br>
 &nbsp; &nbsp;def __init__(self, s):<br>
 &nbsp; &nbsp; &nbsp; &nbsp;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 &nbsp;Bratislava 25 <br>
Tel.: +421/ 2 / 582 31 174 <br>
Fax: +421/ 2 / 582 31 109 <br>
</font>