[Python] domanda sulle classi

Eriol eriol a huine.org
Mer 15 Nov 2006 17:07:18 CET


Alle 11:49, mercoledė 15 novembre 2006, judge judge ha scritto:

Ciao! Mi permetto di darti qualche consiglio :)

> class Pippo:
>         __col=''
>         __nul=''
>         __typ=''

Penso tu stia utilizzando il __ per rendere un nome privato, giusto? In 
questo caso utilizza il singolo _ al posto del doppio.
Il __ non rende un nome privato nel senso di Java: viene effettuato un 
name mangling in modo da aggiungere il nome della classe a quel nome.
Quindi e` comunque possibile accedere a 'col', 'nul', typ' solo che per 
farlo si dovra` utilizzare:
Pippo._Pippo__col
Pippo._Pippo__nul
e cosi` via :)

Quindi se stai utilizzando il __ per il private del Java, cambialo un un 
_: il _ rappresenta la *convenzione* che specifica ad un altro developer 
che quel nome e` da intendersi come dettaglio implementativo e quindi non 
va utilizzato. I nomi preceduti da _ non vengono importati con un "from 
miomodulo import *".

Il __ e` nato per risolvere un differente problema. Se ho le seguenti 
classi:

class Foo(object):
    def m1(self):
        self.x = 1
    def m2(self):
        print self.x

class Bar(object):
    def ma(self):
        self.x = 0
    def mb(self):
        print self.x

class FooBar(Foo, Bar): pass

Un'istanza di FooBar si ritrovera` con un attributo x il cui valore 
dipende dall'ultima classe lo ha assegnato. Nella pratica:

>>> v = FooBar()
>>> v.m1()
>>> v.m2()
1

Se adesso chiamassi il metodo mb della classe Bar:
>>> v.mb()
1

Analogamente:
>>> v.ma()
>>> v.mb()
0
>>> v.m2()
0

Questo avviene perche` tutti gli assegnamenti a self.x referenziano sempre 
la stessa istanza (v) indifferentemente da quale classe utilizzi tale 
nome: esiste un solo attributo x nell'istanza v!

Per evitare tale problema si ricorre al __:


class Foo(object):
    def m1(self):
        self.__x = 1
    def m2(self):
        print self.__x

class Bar(object):
    def ma(self):
        self.__x = 0
    def mb(self):
        print self.__x

class FooBar(Foo, Bar): pass

Infatti:
>>> v = FooBar()
>>> v.m1()
>>> v.ma()

>>> v.m2()
1
>>> v.mb()
0


>         def setColumn(self,name):
>                 self.__col=name
>         [...]
>         def getColumn(self):
>                 return self.__col


Non hai bisogno di utilizzare getter e setter, Python ha le property (le 
puoi usare solo per le classi new style) ;)

Trovi un esempio qui (la funzione property):
http://docs.python.org/lib/built-in-funcs.html

Ciao!

-- 
 Eriol - *p = NULL; - EIBTI 
 GPG Key ID 297BE0CA


Maggiori informazioni sulla lista Python