Re: [Python] Ereditarietà tra classi: un semplice esempio pratico da chiarire

2014-11-21 Per discussione Marco Ippolito
Mille grazie Daniele delle tue interessanti spiegazioni.
Ammetto che non sapevo che si potesse usare un costrutto del tipo:
class NomeClasse(Super):
def __init__(self, variabili,., **kwargs):
super(NomeClasse, self).__init__(variab_super, **kwargs)

Hai ragione nel dire che se vengono passati tanti parametri alla
classe, vuol dire che bisogna riguardare il codice, e magari
suddividerlo in più classi.

Marco

Il 21 novembre 2014 20:41, Daniele Varrazzo  ha scritto:
> On 2014-11-21 17:53, Marco Ippolito wrote:
>>
>> Ciao Daniele,
>> ti ringrazio per l'aiuto.
>>
>> Ho modificato l'esempio, passando tutte le variabili locali (nome,
>> cognome, citta) al costruttore di sub. E così funziona (come vedi
>> sotto).
>>
>> #!/usr/bin/python
>>
>> class Super:
>> def __init__(self, nome, cognome, indirizzo):
>> self.nome = nome
>> self.cognome = cognome
>> self.indirizzo = indirizzo
>> self.nome_intero = '%s %s' % (self.nome, self.cognome)
>>
>> def super_meth_1(self):
>> return '%s abita in %s' % (self.nome_intero, self.indirizzo)
>>
>> def get_super_result(self):
>> return self.super_meth_1()
>>
>> class Sub(Super):
>> def __init__(self, nome, cognome, indirizzo, cosa_fa):
>> Super.__init__(self, nome, cognome, indirizzo)
>> self.cosa_fa = cosa_fa
>>
>> def sub_meth_1(self):
>> return '%s  %s' % (self.nome_intero, self.cosa_fa)
>>
>> def get_sub_meth_1(self):
>> return self.sub_meth_1()
>>
>>
>> if __name__ == '__main__':
>>
>> nome_f = 'Marco'
>> cognome_f = 'Ippolito'
>> abita_f = 'Milano'
>> super_class = Super(nome_f, cognome_f, abita_f)
>> ris_super = super_class.get_super_result()
>> print "ris_super: ", ris_super
>> cosa_f = 'suona'
>> sub = Sub(nome_f, cognome_f, abita_f, cosa_f)
>> ris_sub_1 = sub.get_sub_meth_1()
>> print "ris_sub_1: ", ris_sub_1
>> ris_sub_2 = sub.get_super_result()
>> print "ris_sub_2: ", ris_sub_2
>>
>> ./classInheritage.py
>> ris_super:  Marco Ippolito abita in Milano
>> ris_sub_1:  Marco Ippolito  suona
>> ris_sub_2:  Marco Ippolito abita in Milano
>>
>> C'è un modo per passare far sì che nel main passi a Sub solo le
>> variabili che lo "differenziano" (specializzano) rispetto a Super?
>> Cioè c'è un modo per far sì che io possa passare in "main" solo la
>> variabile "cosa_f"?
>
>
> Nel caso in esempio si fa male. Il pattern migliore e` quello di elencare
> gli argomenti.
>
> La cosa comincia ad essere utile se stabilisci che i costruttori delle tue
> classi debbano essere chiamati solo con argomenti keyword, ovvero, se
> stabilisci che chiamerai
>
> sub = Sub(nome=nome_f, cognome=cognome_f, abita=abita_f, cosa_fa=cosa_f)
>
> allora puoi usare **kwargs e fare:
>
>   class Super:
>   def __init__(self, nome, cognome, indirizzo):
>   self.nome = nome
>   self.cognome = cognome
>   self.indirizzo = indirizzo
>   self.nome_intero = '%s %s' % (self.nome, self.cognome)
>
>   class Sub(Super):
>   def __init__(self, cosa_fa, **kwargs):
>   Super.__init__(self, **kwargs)
>   self.cosa_fa = cosa_fa
>
> considerando che tipicamente definirai il costruttore solo in un punto ma lo
> chiamerai in diversi punti ti conviene essere piu` verboso nelle definizioni
> degli __init__ e risparmiare nell'invocazioe, quindi lasciare le cose come
> stanno.
>
> Questa non e` l'unica cosa che si potrebbe tenere in considerazione pero`.
> Il tuo e` un esempio di studio, che non ha veri vincoli. In casi piu` reali
> potresti avere una gerarchia di oggetti dove pochi argomenti (tipo fino a 3,
> ma meno sono e meglio e`) andranno *sempre* specificati per ogni oggetto
> della gerarchia, mentre ci puo` essere un turbinare di argomenti che sono a)
> opzionali e b) specifici solo di certe sottoclassi. In questo caso il modo
> migliore (secondo me, YMMV) di organizzare il codice e` quello di passare
> gli argomenti fondamentali in maniera posizionale (potrebbero anche essere
> passati con keyword, l'importante e` mantenere la possibilita` di fare
> entrambe le cose) e usare **kwargs per tutti gli altri, in modo da ignorare
> quelli che non si conoscono ma di propagarli.
>
> Per esempio (non testato, ovviamente):
>
> class Persona(object):
> def __init__(self, nome):
> self.nome = nome
>
> class Lavoratore(Persona):
> def __init__(self, nome, ruolo, salario=None, **kwargs):
> super(Lavoratore, self).__init__(nome, **kwargs)
> self.ruolo = ruolo
> self.salario = salario
>
> class Studente(Persona):
> def __init__(self, nome, scuola, classe=None, **kwargs):
> super(Studente, self).__init__(nome, **kwargs)
> self.scuola = ...
>
> class StudenteUniversitario(Studente):
> def __init__(self, nome, fuoricorso_dal=None, **kwargs):
> super(StudenteUniversitario, self).__init__

Re: [Python] Ereditarietà tra classi: un semplice esempio pratico da chiarire

2014-11-21 Per discussione Daniele Varrazzo

On 2014-11-21 17:53, Marco Ippolito wrote:

Ciao Daniele,
ti ringrazio per l'aiuto.

Ho modificato l'esempio, passando tutte le variabili locali (nome,
cognome, citta) al costruttore di sub. E così funziona (come vedi
sotto).

#!/usr/bin/python

class Super:
def __init__(self, nome, cognome, indirizzo):
self.nome = nome
self.cognome = cognome
self.indirizzo = indirizzo
self.nome_intero = '%s %s' % (self.nome, self.cognome)

def super_meth_1(self):
return '%s abita in %s' % (self.nome_intero, self.indirizzo)

def get_super_result(self):
return self.super_meth_1()

class Sub(Super):
def __init__(self, nome, cognome, indirizzo, cosa_fa):
Super.__init__(self, nome, cognome, indirizzo)
self.cosa_fa = cosa_fa

def sub_meth_1(self):
return '%s  %s' % (self.nome_intero, self.cosa_fa)

def get_sub_meth_1(self):
return self.sub_meth_1()


if __name__ == '__main__':

nome_f = 'Marco'
cognome_f = 'Ippolito'
abita_f = 'Milano'
super_class = Super(nome_f, cognome_f, abita_f)
ris_super = super_class.get_super_result()
print "ris_super: ", ris_super
cosa_f = 'suona'
sub = Sub(nome_f, cognome_f, abita_f, cosa_f)
ris_sub_1 = sub.get_sub_meth_1()
print "ris_sub_1: ", ris_sub_1
ris_sub_2 = sub.get_super_result()
print "ris_sub_2: ", ris_sub_2

./classInheritage.py
ris_super:  Marco Ippolito abita in Milano
ris_sub_1:  Marco Ippolito  suona
ris_sub_2:  Marco Ippolito abita in Milano

C'è un modo per passare far sì che nel main passi a Sub solo le
variabili che lo "differenziano" (specializzano) rispetto a Super?
Cioè c'è un modo per far sì che io possa passare in "main" solo la
variabile "cosa_f"?


Nel caso in esempio si fa male. Il pattern migliore e` quello di 
elencare gli argomenti.


La cosa comincia ad essere utile se stabilisci che i costruttori delle 
tue classi debbano essere chiamati solo con argomenti keyword, ovvero, 
se stabilisci che chiamerai


sub = Sub(nome=nome_f, cognome=cognome_f, abita=abita_f, 
cosa_fa=cosa_f)


allora puoi usare **kwargs e fare:

  class Super:
  def __init__(self, nome, cognome, indirizzo):
  self.nome = nome
  self.cognome = cognome
  self.indirizzo = indirizzo
  self.nome_intero = '%s %s' % (self.nome, self.cognome)

  class Sub(Super):
  def __init__(self, cosa_fa, **kwargs):
  Super.__init__(self, **kwargs)
  self.cosa_fa = cosa_fa

considerando che tipicamente definirai il costruttore solo in un punto 
ma lo chiamerai in diversi punti ti conviene essere piu` verboso nelle 
definizioni degli __init__ e risparmiare nell'invocazioe, quindi 
lasciare le cose come stanno.


Questa non e` l'unica cosa che si potrebbe tenere in considerazione 
pero`. Il tuo e` un esempio di studio, che non ha veri vincoli. In casi 
piu` reali potresti avere una gerarchia di oggetti dove pochi argomenti 
(tipo fino a 3, ma meno sono e meglio e`) andranno *sempre* specificati 
per ogni oggetto della gerarchia, mentre ci puo` essere un turbinare di 
argomenti che sono a) opzionali e b) specifici solo di certe 
sottoclassi. In questo caso il modo migliore (secondo me, YMMV) di 
organizzare il codice e` quello di passare gli argomenti fondamentali in 
maniera posizionale (potrebbero anche essere passati con keyword, 
l'importante e` mantenere la possibilita` di fare entrambe le cose) e 
usare **kwargs per tutti gli altri, in modo da ignorare quelli che non 
si conoscono ma di propagarli.


Per esempio (non testato, ovviamente):

class Persona(object):
def __init__(self, nome):
self.nome = nome

class Lavoratore(Persona):
def __init__(self, nome, ruolo, salario=None, **kwargs):
super(Lavoratore, self).__init__(nome, **kwargs)
self.ruolo = ruolo
self.salario = salario

class Studente(Persona):
def __init__(self, nome, scuola, classe=None, **kwargs):
super(Studente, self).__init__(nome, **kwargs)
self.scuola = ...

class StudenteUniversitario(Studente):
def __init__(self, nome, fuoricorso_dal=None, **kwargs):
super(StudenteUniversitario, self).__init__(nome, **kwargs)
...

Il nome puoi passarlo con keyword o meno, gli altri argomenti devono 
avere una keyword.


p1 = StudenteUniversitario("Tizio Caio", scuola="Anormale", 
fuoricorso_dal=1996)

p2 = Lavoratore(nome="Pinco Pallini", ruolo=...)


Avere classi che richiedono un gran numero di parametri posizionali da 
passare non e` una buona cosa: e` facile sbagliare nel passaggio. Se gli 
argomenti cominciano ad essere tanti e` meglio richiedere che vengano 
passati con keyword (ma e` ancora meglio chiedersi come mai ci siano 
tanti parametri e cambiare qualcosa nel codice).



-- Daniele

___
Python mailing list
Python@lists.python.it
http://lists.python.it/mail

Re: [Python] Ereditarietà tra classi: un semplice esempio pratico da chiarire

2014-11-21 Per discussione Marco Ippolito
Ciao Daniele,
ti ringrazio per l'aiuto.

Ho modificato l'esempio, passando tutte le variabili locali (nome,
cognome, citta) al costruttore di sub. E così funziona (come vedi
sotto).

#!/usr/bin/python

class Super:
def __init__(self, nome, cognome, indirizzo):
self.nome = nome
self.cognome = cognome
self.indirizzo = indirizzo
self.nome_intero = '%s %s' % (self.nome, self.cognome)

def super_meth_1(self):
return '%s abita in %s' % (self.nome_intero, self.indirizzo)

def get_super_result(self):
return self.super_meth_1()

class Sub(Super):
def __init__(self, nome, cognome, indirizzo, cosa_fa):
Super.__init__(self, nome, cognome, indirizzo)
self.cosa_fa = cosa_fa

def sub_meth_1(self):
return '%s  %s' % (self.nome_intero, self.cosa_fa)

def get_sub_meth_1(self):
return self.sub_meth_1()


if __name__ == '__main__':

nome_f = 'Marco'
cognome_f = 'Ippolito'
abita_f = 'Milano'
super_class = Super(nome_f, cognome_f, abita_f)
ris_super = super_class.get_super_result()
print "ris_super: ", ris_super
cosa_f = 'suona'
sub = Sub(nome_f, cognome_f, abita_f, cosa_f)
ris_sub_1 = sub.get_sub_meth_1()
print "ris_sub_1: ", ris_sub_1
ris_sub_2 = sub.get_super_result()
print "ris_sub_2: ", ris_sub_2

./classInheritage.py
ris_super:  Marco Ippolito abita in Milano
ris_sub_1:  Marco Ippolito  suona
ris_sub_2:  Marco Ippolito abita in Milano

C'è un modo per passare far sì che nel main passi a Sub solo le
variabili che lo "differenziano" (specializzano) rispetto a Super?
Cioè c'è un modo per far sì che io possa passare in "main" solo la
variabile "cosa_f"?

Ti ringrazio.
Marco
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] Ereditarietà tra classi: un semplice esempio pratico da chiarire

2014-11-21 Per discussione Daniele Varrazzo

On 2014-11-21 17:35, Daniele Varrazzo wrote:

On 2014-11-21 17:19, Marco Ippolito wrote:


class Sub(Super):
def __init__(self, indirizzo,cosa_fa):
Super.__init__(self, nome, cognome, indirizzo)
self.cosa_fa = cosa_fa

...


ora...


No, anche prima...



se modifico la Sub class in questo modo:



class Sub(Super):
def __init__(self, cosa_fa):
Super.__init__(self, nome, cognome, citta)
self.cosa_fa = cosa_fa



Ne' questo ne' quello di sopra sono corretti. Forse hai delle
variabili globali che accidentalmente si chiamano nome e cognome ma
non ne hai una che si chiama citta.


Ah si`, giusto: le variabili sono definite qui:


if __name__ == '__main__':

nome = 'Marco'
cognome = 'Ippolito'


Il costruttore accidentalmente pesca questi valori dal namespace 
globale. Questo e` un comportamento sbagliato. Chiamale in un altro modo 
e vedrai che avrai un'eccezione anche nel primo caso.


-- Daniele
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] Ereditarietà tra classi: un semplice esempio pratico da chiarire

2014-11-21 Per discussione Daniele Varrazzo

On 2014-11-21 17:19, Marco Ippolito wrote:


class Sub(Super):
def __init__(self, indirizzo,cosa_fa):
Super.__init__(self, nome, cognome, indirizzo)
self.cosa_fa = cosa_fa

...


ora...


No, anche prima...



se modifico la Sub class in questo modo:



class Sub(Super):
def __init__(self, cosa_fa):
Super.__init__(self, nome, cognome, citta)
self.cosa_fa = cosa_fa



Ne' questo ne' quello di sopra sono corretti. Forse hai delle variabili 
globali che accidentalmente si chiamano nome e cognome ma non ne hai una 
che si chiama citta.


nome e cognome sono variabili locali: le devi passare al costruttore di 
sub, che nel primo caso potrebbe essere ad esempio:


class Sub(Super):
def __init__(self, nome, cognome, indirizzo, cosa_fa):
Super.__init__(self, nome, cognome, indirizzo)
self.cosa_fa = cosa_fa

Il secondo caso "funziona bene", ovvero ti da` un errore. Anche il primo 
dovrebbe.



-- Daniele
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


[Python] Ereditarietà tra classi: un semplice esempio pratico da chiarire

2014-11-21 Per discussione Marco Ippolito
Ciao a tutti,
con l'obiettivo di capire fino in fondo alcuni aspetti
dell'ereditarietà tra classi che non mi sono ancora chiari (pensavo lo
fossero), mi sono scritto un esempio forzatamente banale.

#!/usr/bin/python

class Super:
def __init__(self, nome, cognome, citta):
self.nome = nome
self.cognome = cognome
self.citta = citta
self.nome_intero = '%s %s' % (self.nome, self.cognome)

def super_meth_1(self):
return '%s abita a %s' % (self.nome_intero, self.citta)

def get_super_result(self):
return self.super_meth_1()

class Sub(Super):
def __init__(self, indirizzo,cosa_fa):
Super.__init__(self, nome, cognome, indirizzo)
self.cosa_fa = cosa_fa

def sub_meth_1(self):
return '%s  %s' % (self.nome_intero, self.cosa_fa)

def get_sub_meth_1(self):
return self.sub_meth_1()


if __name__ == '__main__':

nome = 'Marco'
cognome = 'Ippolito'
abita = 'Milano'
super_class = Super(nome, cognome, abita)
ris_super = super_class.get_super_result()
print 'ris_super: ', ris_super
cosa = 'suona'
sub = Sub(abita, cosa)
ris_sub_1 = sub.get_sub_meth_1()
print "ris_sub_1: ", ris_sub_1
ris_sub_2 = sub.get_super_result()
print "ris_sub_2: ", ris_sub_2

time ./classInheritage2.py
ris_super:  Marco Ippolito abita a Milano
ris_sub_1:  Marco Ippolito  suona
ris_sub_2:  Marco Ippolito abita a Milano

ora...

se modifico la Sub class in questo modo:

#!/usr/bin/python

class Super:
def __init__(self, nome, cognome, citta):
self.nome = nome
self.cognome = cognome
self.citta = citta
self.nome_intero = '%s %s' % (self.nome, self.cognome)

def super_meth_1(self):
return '%s abita a %s' % (self.nome_intero, self.citta)

def get_super_result(self):
return self.super_meth_1()

class Sub(Super):
def __init__(self, cosa_fa):
Super.__init__(self, nome, cognome, citta)
self.cosa_fa = cosa_fa

def sub_meth_1(self):
return '%s  %s' % (self.nome_intero, self.cosa_fa)

def get_sub_meth_1(self):
return self.sub_meth_1()


if __name__ == '__main__':

nome = 'Marco'
cognome = 'Ippolito'
abita = 'Milano'
super_class = Super(nome, cognome, abita)
ris_super = super_class.get_super_result()
print 'ris_super: ', ris_super
cosa = 'suona'
sub = Sub(cosa)
ris_sub_1 = sub.get_sub_meth_1()
print "ris_sub_1: ", ris_sub_1
ris_sub_2 = sub.get_super_result()
print "ris_sub_2: ", ris_sub_2

l'ouput risulta:

ris_super:  Marco Ippolito abita a Milano
Traceback (most recent call last):
  File "./classInheritage3.py", line 37, in 
sub = Sub(cosa)
  File "./classInheritage3.py", line 18, in __init__
Super.__init__(self, nome, cognome, citta)
NameError: global name 'citta' is not defined

Cosa differenzia l'attributo "citta" dagli altri attributi ("nome" e
"cognome") anche essi presenti in Super class?
Qual è il modo corretto per far sì che Sub class erediti da Super
class gli attributi "nome, "cognome" e "citta" ?

Marco
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] Python e saturazione CPU

2014-11-21 Per discussione Riccardo Brazzale
Il giorno 21 novembre 2014 00:03, Enrico Bianchi 
ha scritto:

>
>>  Per la chiusura dei file, suggerirei di usare il costrutto with:
>
> with open(filein, 'r') as fin, open(writeto + fileout, "w") as fou:
> #resto del codice


Per prima cosa GRAZIE a tutti.

Il problema, come sospettavo, in realta' era sulla vm. Ho abilitato
l'accelerazione 3D per lo schermo e il problema e' sparito.

Ciao.

-- 
Riccardo Brazzale
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python


Re: [Python] ctypes e puntatore ad un array di stringhe

2014-11-21 Per discussione Marco Giusti
On Tue, Nov 18 2014, Marco Giusti wrote:
> Salve a tutti,
> 
> con ctypes vorrei richiamare una funzione C che ritorna **char. La
> funzione in causa assegna la memoria per le singole stringhe e per
> l'array stesso e lascia al chiamante l'onere di liberarla. Sebbene con
> ctypes riesca ad accedere ai singoli valori, non riesco ad accedere
> all'area di memoria puntate e di conseguenza non riesco a liberarla.

Penso di aver risolto giocando con i puntatori come in C. Spero di non
andare all'inferno per questo .)

Per la cronaca allego quanto fatto così, se avete voglia, potete anche
verificare la correttezza.

m.
#include 
#include 
#include "my.h"

int main(int argc, char *argv[])
{
	char **env = NULL;
	int i;

	if ((env = getlist()) == NULL) {
		perror("getlist");
		exit(1);
	}

	for (i=0; env[i] != NULL; i++)
		printf("%s\n", env[i]);
	exit(0);
}
all: libmy.so a.out

run: libmy.so
LD_LIBRARY_PATH=. python my.py

libmy.so: my.c my.h
gcc -Wall -fPIC -g -c my.c
gcc -shared -Wl,-soname,libmy.so.1 -o libmy.so.1.0 my.o
ln -sf libmy.so.1.0 libmy.so.1
ln -sf libmy.so.1 libmy.so

a.out: libmy.so main.c
gcc -Wall -I. -L. -lmy -g main.c 

clean:
rm my.o a.out libmy.so*
#include 
#include 

char **getlist(void)
{
	char **env = NULL;

	if ((env = malloc(3 * sizeof(char *))) != NULL) {
		env[0] = NULL;
		env[1] = NULL;
		env[2] = NULL;
		if ((env[0] = strdup("hello")) != NULL) {
			if ((env[1] = strdup("world")) != NULL)
return env;
			else
free(env[0]);
		}
		free(env);
	}
	return NULL;
}
char **getlist(void);
import ctypes
import ctypes.util

_libmy = ctypes.CDLL("libmy.so.1")
_libc = ctypes.CDLL(ctypes.util.find_library("c"))
_sizeof_pointer = ctypes.sizeof(ctypes.c_void_p)


def getlist():
arr = _libmy.getlist()
ret = []
off = 0
p = ctypes.c_int.from_address(arr).value
while p:
ret.append(ctypes.string_at(p))
_libc.free(p)
off += _sizeof_pointer
p = ctypes.c_int.from_address(arr + off).value
_libc.free(arr)
return ret

if __name__ == "__main__":
print getlist()
___
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python