[Python-es] Problemas con clases

Chema Cortes pych3m4 en gmail.com
Dom Abr 28 14:48:56 CEST 2013


Te respondo muy rápido entrelíneas, a las dos preguntas y algunas
cosas más. Al final he añadido algunos consejos:

El día 28 de abril de 2013 02:23, Lucas Alvarez
<alvarezlucas en gmail.com> escribió:
> Hola gente, estoy dando mis primeros pasos con las clases en python y me
> encuentro con ciertos errores que no puedo solucionar...
> Si alguien me puede hacer ver como manejar el tipo de error que me larga les
> agradeceria....
> El enunciado es el siguiente....
> Implementar una clase lectura que almacena informacion sobre la lectura de
> un determinado libro. Esta clase tiene como variable instancia una
> referencia a un  objeto Libro y el numero de la pagina que se esta leyendo.
> Modificar para poder almacenar informacion de los libros que va leyendo una
> persona.  Implementar los siguientes metodos:
> libroLeido(titulo) retorna True o False
> darSinopsis(titulo) retorna sinopsis
> LeidosAnioEdicion(x) retorna todos los libros leidos que estan leidos y su
> año de edicion es una año X recibido por parametro.
> darLibrosPorAutor(nombreAutor) retorna los libros leidos y autor coincide.
>
> me larga el error o no... LecturaFinal.Lectura object at 0xb74a77ec Cuando
> llamo a librosleidos.darLibros_X_Autor("Jorge")
>
> el codigo que tengo en un archivo es el siguiente.
>
>
>
>
>
>
>
> <code>#!/usr/bin/python
> # -*- coding: utf:8 -*-
> '''
> Created on Apr 17, 2013
>
> @author: manseka
> '''
>
>
> class Libro(object):
>
>     def __init__(self, titulo, cantPag, sinopsis, anoedicion, autor):
>         '''
>         Constructor
>         '''
>         self.__titulo = titulo
>         self.__cantPag = cantPag
>         self.__sinopsis = sinopsis
>         self.__anoedicion = anoedicion
>         self.__autor = autor
>
>
>     def get_titulo(self):
>         return self.__titulo
>
>
>     def get_cant_pag(self):
>         return self.__cantPag
>
>
>     def get_sinopsis(self):
>         return self.__sinopsis
>
>
>     def get_anoedicion(self):
>         return self.__anoedicion
>
>
>     def get_autor(self):
>         return self.__autor
>
>
>     def set_titulo(self, value):
>         self.__titulo = value
>
>
>     def set_cant_pag(self, value):
>         self.__cantPag = value
>
>
>     def set_sinopsis(self, value):
>         self.__sinopsis = value
>
>
>     def set_anoedicion(self, value):
>         self.__anoedicion = value
>
>
>     def set_autor(self, value):
>         self.__autor =value
>
>     def __str__(self):
>         return ("""
>         Titulo del Libro:   %s
>         Cantidad de Paginas %s
>         Año Edicion:        %s
>         ······················································
>         Sinopsis:  %s
>         ······················································
>         Autor:
>         %s
>         ······················································
>         """) % (self.get_titulo(), self.get_cant_pag(), self.get_anoedicion(),self.get_sinopsis(), self.get_autor())
>     def devuelveLibro(self):
>         return ("""
>         Titulo del Libro:   %s
>         Cantidad de Paginas %s
>         Año Edicion:        %s
>         ······················································
>         Sinopsis:  %s
>         ······················································
>         Autor:
>         %s
>         ······················································
>         """) % (self.get_titulo(), self.get_cant_pag(), self.get_anoedicion(),self.get_sinopsis(), self.get_autor())

Estos dos métodos podían llamarse el uno al otro para simplificar código.


>
>
> class Persona(object):
>     def __init__(self, nombre, apellido, tipoDNI, numDNI):
>         self.__nombre = nombre
>         self.__apellido = apellido
>         self.__tipoDNI = tipoDNI
>         self.__numDNI = numDNI
>
>     def get_nombre(self):
>         return self.__nombre
>
>
>     def get_apellido(self):
>         return self.__apellido
>
>
>     def get_tipo_dni(self):
>         return self.__tipoDNI
>
>
>     def get_num_dni(self):
>         return self.__numDNI
>
>
>     def set_nombre(self, value):
>         self.__nombre = value
>
>
>     def set_apellido(self, value):
>         self.__apellido = value
>
>
>     def set_tipo_dni(self, value):
>         self.__tipoDNI = value
>
>
>     def set_num_dni(self, value):
>         self.__numDNI = value
>
>     def __str__(self):
>         return ("""
>         Nombre: %s
>         Apellido: %s
>         Tipo: %s
>         DNI nº: %s """) % (self.get_nombre(), self.get_apellido(), self.get_tipo_dni(), self.get_num_dni())
>
> class Lectura(object):
>     def __init__(self, lector, libro, nropag):
>         self.__lector =lector
>         self.__libro= libro
>         self.__nropag= nropag
>
>     def get_lector(self):
>         return self.__lector
>
>
>     def get_libro(self):
>         return self.__libro
>
>     def get_nropag(self):
>         return self.__nropag
>
>
>     def set_lector(self, value):
>         self.__lector = value
>
>
>     def set_libro(self, value):
>         self.__libro = value
>
>     def set_nropag(self, value):
>         self.__nropag = value
>
>     def siguientePagina(self):
>         pasar = self.get_nropag() + 1
>         self.set_nropag(pasar)
>
>     def retrocederPagina(self):
>         anterior = self.get_nropag() - 1
>         self.set_nropag(anterior)
>
>
> class LibroLeido(object):
>     def __init__(self):
>         self.__librosLeidos=[]
>
>     def get_libros_leidos(self):
>         return self.__librosLeidos
>
>
>     def set_libros_leidos(self, value):
>         self.__librosLeidos = value

Aquí no estás "añadiendo" libros, sólo estás sustituyendo la lista de
libros por un valor.


>
>     def agregaLectura(self, lectura):
>         self.get_libros_leidos().append(lectura)
>
>     def libroLeido(self, titulo):
>         for i in self.get_libros_leidos()[0].get_libro().get_titulo():
>             if self.get_libros_leidos()[0].get_libro().get_titulo() == titulo:
>                 return True
>             else:
>                 return False

Duele a los ojos ver un return en medio de un bucle, más aún siendo
una sentencia if tan trivial.

Investiga cómo buscar elementos en un lista con el operador "in"


>
>     def darSinopsis(self, titulo):
>         x=0
>
>         for i in self.get_libros_leidos()[x].get_libro().get_titulo():
>             # print "Valor de X ---> ",x
>             if self.get_libros_leidos()[x].get_libro().get_titulo() == titulo:
>                 return self.get_libros_leidos()[x].get_libro().get_sinopsis()
>             x = x + 1

Ibidem: duele ver un return dentro de un bucle. No tengo nada claro
qué quieres hacer aquí y dudo que vaya bien. Procura no modificar las
variables de control dentro del bucle.


>
>     def AnoEdicion(self,edicion):
>         x= 1
>         i= (len (self.get_libros_leidos()))
>         print "Valor de i ---->>>>", i
>         for i in self.get_libros_leidos()[x].get_libro().get_titulo():
>             # print "Valor de X ---> ",x
>             if self.get_libros_leidos()[x].get_libro().get_anoedicion() == edicion:
>                 print """
>                 Titulo:      %s
>                 Paginas:     %s
>                 Sinopsis:    %s
>                 Año Edicion: %s
>                 Autor:       %s""" %
> (self.get_libros_leidos()[x].get_libro().get_titulo(),self.get_libros_leidos()[x].get_libro().get_cant_pag(),
> self.get_libros_leidos()[x].get_libro().get_sinopsis(),self.get_libros_leidos()[x].get_libro().get_anoedicion(),
> self.get_libros_leidos()[x].get_libro().get_autor())
>                 print
> "----------------------------------------------------------------"
>             #self.get_libros_leidos()[x].get_libro().get_anoedicion()
>             x = x + 1
>
>
>     def AnoEdicion2(self,edicion):
>         llibros=[]
>         for unaLectura in self.get_libros_leidos():
>             objLibro = unaLectura.get_libro()
>             anio = objLibro.get_anoedicion()
>             print  "aÑos", anio
>             if anio == edicion:
>                 llibros.append(objLibro)
>
>             return llibros
>
>
>     def darLibros_X_Autor(self, autor):
>
>         librosa=[]
>         for unaLectura2 in self.get_libros_leidos():
>             objLibro2 = unaLectura2.get_libro()
>             autor2 = objLibro2.get_autor()
>             print unaLectura2

Si te fijas en el texto que saca:

  libros leidos por Autor: $$$$$$$ --> <LecturaFinal.Lectura object at
<0xb74a77ec>

Estás intentando imprimir un objeto "LecturaFinal.Lectura". Si quieres
ver algo más, tendrás que iterar sobre este objeto para imprimir cada
libro.



>             if autor2 == autor:
>                 librosa.append(self.get_libros_leidos().get_libro())
>
>             return str(librosa)
>
>         """
>         x= 1
>         i= (len (self.get_libros_leidos()))
>         print "Valor de i ---->>>>", i
>         for i in self.get_libros_leidos()[x].get_libro().get_titulo():
>             # print "Valor de X ---> ",x
>             if self.get_libros_leidos()[x].get_libro().get_autor() == autor:
>
>                 print """
>                 #  Titulo:      %s
>                 #  Paginas:     %s
>                 # Sinopsis:    %s
>                 # Año Edicion: %s
>                 # Autor:       %s""" %
> (self.get_libros_leidos()[x].get_libro().get_titulo(),self.get_libros_leidos()[x].get_libro().get_cant_pag(),
> self.get_libros_leidos()[x].get_libro().get_sinopsis(),self.get_libros_leidos()[x].get_libro().get_anoedicion(),
> self.get_libros_leidos()[x].get_libro().get_autor())
>                 #  print
> "----------------------------------------------------------------"
>                 #self.get_libros_leidos()[x].get_libro().get_anoedicion()
>                 # x = x + 1
>      </code>
>
> y el codigo para probar es....
> <code>#!/usr/bin/python
> # -*- coding: utf:8 -*-
>
> from LecturaFinal import Libro
> from LecturaFinal import Persona
> from LecturaFinal import Lectura
> from LecturaFinal import LibroLeido
>
> def mostrarLista(l):
>     for elem in l:
>         print elem
>
>
>
> lector1 = Persona("Juan", "Perez","DNI", "22.203.121")
> lector2 = Persona("Pedro", "Matam","LC","2.121.212")
> autor = Persona("Jorge","Borges","LC", "6.191.212")
> autor2 = Persona("Sergio","Borg","LC", "12.191.212")
>
> libro = Libro("El Aleph", "12", "El libro de borges", "2010", autor)
> libro2 = Libro("Neuquenia", "1212", "Libro de Neuquen","2010",  autor2)
>
> lectura1 = Lectura(lector1, libro,12)
> lectura = Lectura(lector1, libro2,122)
> lectura2 = Lectura(lector2, libro2, 67)
>
> librosleidos = LibroLeido()
> librosleidos.agregaLectura(lectura1)
> librosleidos.agregaLectura(lectura)
> librosleidos.agregaLectura(lectura2)
>
> print "Esta Leido?  ---> ", librosleidos.libroLeido("El Aleph")
>
> # print librosleidos.get_libros_leidos()[0].get_libro().get_titulo()
> # print librosleidos.get_libros_leidos()[1].get_libro().get_titulo()
>
>
> print "Sinopsis --->", librosleidos.darSinopsis("El Aleph")
> print "Sinopsis --->", librosleidos.darSinopsis("Neuquenia")
>
> print "libros leidos por Año edicon ----->",
>
> l = librosleidos.AnoEdicion2("2010")
> mostrarLista(l)
> #mostrarLista(librosleidos.get_libros_leidos())
> print "libros leidos por Autor: $$$$$$$ -->",
> librosleidos.darLibros_X_Autor("Jorge")
> #print "libros leidos por anoedicon", librosleidos.AnoEdicion("2010")</code>
>
> cuando lo corro me larga el error
>
> libros leidos por Autor: $$$$$$$ --> <LecturaFinal.Lectura object at
> 0xb74a77ec>
>
> y solo me larga un libro cuando corro librosleidos x año de edicion...
>
> espero haberme explicado bien y me puedan ayudar.... desde ya agradecido...
>

Para códigos tan largos, te recomiendo usar algún servicio tipo
"pastebin" (te recomendaría gist.github.com si tienes ahí una cuenta,
pero hay muchos otros).

Lo segundo es que no es necesario crear "accesores" para todos los
atributos. Ésta es una técnica habitual en otros lenguajes OOP que
esperan sobrecargar estos atributos, pero en python no afecta en nada.

El método __init__ es un "inicializador", no un "constructor" como lo
llamas al prinicpio (en python, el constructor se llama __new__ )




--
Hyperreals *R: http://ch3m4.org/blog
Quarks, bits y otras criaturas infinitesimales


Más información sobre la lista de distribución Python-es