Los métodos de instancia en Python dan vida a los objetos: permiten consultar, validar y modificar su estado interno con precisión. Aquí verás cómo aplicar self, diseñar str, y crear métodos como prestar y devolver en una clase Libro con ISBN y campo booleano de disponibilidad, tal como se mostró al ejecutar python main.py con “Cien años de soledad” y “El Principito”.
¿Qué son los métodos de instancia y cómo usan self?
En Python, los métodos definidos dentro de una clase operan sobre cada instancia usando el parámetro self. Así, cada objeto puede interactuar con sus propios datos, como el campo booleano de disponibilidad.
self referencia la instancia actual: accede a atributos y modifica estado.
disponible como booleano: indica si el libro se puede prestar.
catálogo como lista: agrupa varios libros para iterar e imprimir sus datos con un for.
¿Cómo organizar el catálogo y el campo disponible?
Agrega el ISBN y el booleano disponible al inicializador.
Crea dos libros y añádelos a una lista catálogo.
Recorre con for e imprime cada libro.
classLibro:def__init__(self, titulo, autor, isbn, disponible=True): self.titulo = titulo
self.autor = autor
self.isbn = isbn
self.disponible = disponible
# Ejemplo de usolibro1 = Libro("Cien años de soledad","Gabriel García Márquez","978-0-06-088328-7")libro2 = Libro("El Principito","Antoine de Saint-Exupéry","978-0-15-601219-5")catalogo =[libro1, libro2]for libro in catalogo:# Se mejorará con __str__ más adelanteprint(libro.titulo, libro.autor, libro.isbn, libro.disponible)
¿Cómo mejorar la salida con str y return?
El método especial str se ejecuta automáticamente al hacer print de un objeto. Debe usar self y siempre retornar un string con return. Sin return, aparece un error al imprimir el objeto.
classLibro:def__init__(self, titulo, autor, isbn, disponible=True): self.titulo = titulo
self.autor = autor
self.isbn = isbn
self.disponible = disponible
def__str__(self):# Retornar la representación escrita del libroreturnf"{self.titulo} - {self.autor} | ISBN: {self.isbn} | disponible: {self.disponible}"print(libro1)# Usa __str__ automáticamente
¿Qué fallos comunes evitar con f-strings?
Olvidar la letra “f” en el literal: el mensaje no interpolará variables.
No usar self dentro de str: produce errores o datos incorrectos.
Omitir return: no se imprime la representación del objeto.
¿Cómo implementar prestar y devolver y qué implica el reto “Es popular”?
Inicialmente, cambiar disponibilidad valida si el libro está disponible y lo pone en no disponible. Mejor aún, separar responsabilidades en dos métodos: prestar y devolver. Ambos usan self y retornan mensajes claros para entender qué ocurrió.
classLibro:def__init__(self, titulo, autor, isbn, disponible=True): self.titulo = titulo
self.autor = autor
self.isbn = isbn
self.disponible = disponible
defprestar(self):if self.disponible: self.disponible =Falsereturnf"{self.titulo}: prestado exitosamente."# (La lógica mostró el cambio cuando estaba disponible.)defdevolver(self): self.disponible =Truereturnf"{self.titulo}: ha sido devuelto y disponible nuevamente."
Ejemplo de uso y visualización de los mensajes con print y return:
miolibro = Libro("Cien años de soledad","Gabriel García Márquez","978-0-06-088328-7")print(miolibro.prestar())# "... prestado exitosamente"print(miolibro.devolver())# "... devuelto y disponible nuevamente"
¿Cómo abordar el método “Es popular” con un historial de préstamos?
El reto propone un método Es popular que retorne True si el libro fue prestado más de cinco veces. Para calcularlo, se debe guardar una lista de todos los libros prestados y contar las ocurrencias del libro objetivo.
# Lista global o compartida que registre cada préstamohistorial_prestamos =[]classLibro:def__init__(self, titulo, autor, isbn, disponible=True): self.titulo = titulo
self.autor = autor
self.isbn = isbn
self.disponible = disponible
defprestar(self):if self.disponible: self.disponible =False historial_prestamos.append(self)returnf"{self.titulo}: prestado exitosamente."defdevolver(self): self.disponible =Truereturnf"{self.titulo}: ha sido devuelto y disponible nuevamente."defes_popular(self):return historial_prestamos.count(self)>5
¿Te gustaría compartir cómo diseñarías el historial de préstamos o qué formato de impresión te resulta más claro con str?
classBook: def __init__(self, title, author, isbn, available): self.title= title
self.author= author
self.isbn= isbn
self.available= available
self.lended_count=0 def __str__(self):return f"Title: {self.title}, Author: {self.author}, ISBN: {self.isbn}, Available: {self.available}" def lend_book(self):if self.available: self.available=False self.lended_count+=1return f"'{self.title}' lended and is not available" def return_book(self): self.available=Truereturn f"'{self.title}' returned and available for lending" def is_popular(self):return self.lended_count>=5
Al inicio habia creado una lista y agregado ahi a modo de contador, luego me di cuenta que no era eficiente por que estaba declarando a nivel de clase y no a nivel de instancia, para que cada libro tenga su propio contador prestamos debe ir en __init__, de esta forma es atributo de instancia!
Aqui mi solución:
classLibro:def__init__(self, titulo, autor, isbn, disponible=True,): self.titulo = titulo
self.autor = autor
self.isbn = isbn
self.disponible = disponible
self.prestamos =0#deberia ir aqui para que sea de instanciadef__str__(self):returnf"{self.titulo} por {self.autor} (ISBN: {self.isbn}) - {'Disponible'if self.disponible else'No Disponible'}"defprestar(self):if self.disponible: self.disponible =False self.prestamos +=1returnf"{self.titulo} ha sido prestado."defdevolver(self): self.disponible =Truereturnf"{self.titulo} ha sido devuelto."defes_popular(self):return self.prestamos >5
# ClaseLibroclassLibro: # Método constructor
def __init__(self, titulo, autor, isbn, disponible =True): self.titulo= titulo
self.autor= autor
self.isbn= isbn
self.disponible= disponible
self.prestamos=[] # Lista para guardar los préstamos del libro
# Método para imprimir la representación escrita del libro
def __str__(self):return f"Titulo: {self.titulo} - Autor: {self.autor} - ISBN: {self.isbn} - Disponible: {self.disponible}" # Método para cambiar la disponibilidad del libro
def prestar_libro(self):if self.disponible: self.disponible=False self.prestamos.append(True) # Registrar el préstamo en la lista
return f"El libro *{self.titulo} ha sido prestado" def devolver_libro(self):if self.disponible==False: self.disponible=Truereturn f"El libro *{self.titulo} ha sido devuelto" def es_popular(self): # RetornaTrue si el libro ha sido prestado más de 5 veces
iflen(self.prestamos)>5:return f"El libro *{self.titulo} es popular, ha sido prestado {len(self.prestamos)} veces"# Instancia de la clase Librolibro1 =Libro("El principito","Antoine de Saint-Exupéry","1234567890",True)libro2 =Libro("1984","George Orwell","1234567890",True)print(libro1.prestar_libro())# Lista de libros
listaCatalogo =[libro1, libro2]# Imprimir el catálogo de libros
print(f"Catálogo de libros:")for libro inlistaCatalogo:print(libro)print(libro1.devolver_libro())print(libro1.prestar_libro())print(libro1.devolver_libro())print(libro1.prestar_libro())print(libro1.devolver_libro())print(libro1.prestar_libro())print(libro1.devolver_libro())print(libro1.prestar_libro())print(libro1.devolver_libro())print(libro1.prestar_libro())print(libro1.es_popular())
🧩MÉTODOS DE INSTANCIA EN PYTHON
⚙️ ¿Qué son los métodos de instancia?
Los métodos de instancia son las acciones que puede realizar un objeto.
Permiten que cada uno:
🔍 Consulte su propio estado.
🧠 Valide condiciones internas.
🔄 Modifique sus propios datos.
👉 Son lo que “da vida” a los objetos.
🪞 El papel de self
📌 self es la referencia al objeto actual dentro de la clase.
Sirve para acceder y modificar sus atributos.
🧱 Ejemplo:
def prestar(self):
if self.disponible:
self.disponible = False
🗝️ Recuerda: todos los métodos de instancia deben tener self como primer parámetro.
📚 Clase Libro — Atributos principales
Cada libro guarda su información individual:
📖 titulo → nombre del libro
✍️ autor → autor/a del libro
🔢 isbn → identificador único
✅ disponible (booleano) → indica si puede prestarse
📦 Varios libros pueden guardarse dentro de una lista llamada catalogo.
🔸 Se ejecuta automáticamente al hacer print(objeto).
🔸 Siempre debe retornar un texto con return.
⚠️ Cuida estos errores:
🚫 Olvidar la f en el string.
🚫 No usar self dentro del método.
🚫 Omitir return.
🔄 Métodos de acción: prestar() y devolver()
📤 prestar()
Verifica si el libro está disponible.
Si lo está, cambia disponible = False.
Devuelve un mensaje indicando el préstamo.
📥 devolver()
Restablece disponible = True.
Devuelve un mensaje de confirmación.
def prestar(self):
if self.disponible:
self.disponible = False
return f"{self.titulo}: prestado exitosamente."
def devolver(self):
self.disponible = True
return f"{self.titulo}: ha sido devuelto y disponible nuevamente."
No quedaría mejor así?:
# Metodo def cambiar_disponibilidad(self): self.disponibilidad= not self.disponibilidad
Sí esta es una opción más legible! bien que la propongas!
Reto!
classLibro: def __init__(self, titulo, autor, isbn, disponible =True): self.titulo= titulo
self.autor= autor
self.isbn= isbn
self.disponible= disponible
self.prestados=[] #Se crea la lista vacia
def prestar(self):if self.disponible: self.disponible=False self.prestados.append(self.titulo) #Se agrega cada que se presta
return f'{self.titulo}''prestado exitosamente' def es_popular(self):if self.prestados.count(self.titulo)>5: #Aca se define si es popular
returnTrueelse:returnFalse
classLibro: def __init__(self, titulo, autor, precio, año, disponible): self.titulo= titulo
self.autor= autor
self.precio= precio
self.año= año
self.disponible= disponible
def __str__(self):return f"Titulo: {self.titulo}, Autor: {self.autor}, Precio: {self.precio}, Año: {self.año}, Disponible: {self.disponible}" def prestado(self):if self.disponible: self.disponible=Falsereturn f"El libro {self.titulo} ha sido prestado"else:return f"El libro {self.titulo} no esta disponible" def devuelto(self): self.disponible=Truereturn f"El libro {self.titulo} ha sido devuelto" def guardar_prestado(self):withopen("prestados.txt","a")asarchivo: # if self.disponible==False: archivo.write(f"{self.titulo}\n") # else: # return f"El libro {self.titulo} no esta disponible" def popular(self): contador =0withopen("prestados.txt","r")asarchivo:for linea inarchivo:if linea.strip()== self.titulo: contador +=1if contador >=5:return f"El libro {self.titulo} es popular ({contador} préstamos)"else:return f"El libro {self.titulo} NO es popular ({contador} préstamos)"print(" BIBLIOTECA JS ")print("------------------------------------------------------- \n")primer_libro =Libro("1: El principito","Antoine de Saint-Exupéry",58,2003,True)segundo_libro =Libro("2: El Quijote","Miguel de Cervantes",25,1615,True)tercer_libro =Libro("3: Don Quijote","Miguel de Cervantes",25,1615,True)primer_libro.prestado()segundo_libro.prestado()tercer_libro.devuelto()biblioteca =[primer_libro, segundo_libro, tercer_libro]for libro inbiblioteca:if libro.disponible==False: libro.guardar_prestado()print(libro.popular())
Muy bien! recuerda usar el formato MD. (markdown) para que los comentarios en platzi se vean coloreados como en tu editor de código.
classBook: # create method constructor def __init__(self, title, author, available): self.title= title self.author= author self.available= available self.popularity=0 def __str__(self):return f"{self.title} by {self.author} available at {self.available}" def lend_book(self):if self.available: self.available=Falsereturn f"{self.title} lend successfully"return f"{self.title} not lend a book" def return_book(self):if not self.available: self.available=True self.popularity+=1return f"{self.title} returned successfully"return f"{self.title} not returned book" def book_popular(self):if self.popularity>=5:return f"the book {self.title} is very popular"return f"the book {self.title} not is popular"book_it =Book("IT","Stephen King",True)book_100_years =Book("100 años de soledad","Gabriel Garcia Marquez",True)print( book_it.lend_book())print(book_it.return_book())print( book_it.lend_book())print(book_it.return_book())print( book_it.lend_book())print(book_it.return_book())print( book_it.lend_book())print(book_it.return_book())print( book_it.lend_book())print(book_it.return_book())print(book_it.book_popular())print(book_100_years.book_popular())
¡Solución Reto de la clase!
Me ahorré unas líneas haciendo esto :p
def cambiar_disponibilidad(self):
self.disponible = not self.disponible
classLibro: catalogo =[] prestamos ={}def__init__(self, titulo:str, autor:str, isbn:str, disponible:bool=True): self.titulo = titulo
self.autor = autor
self.isbn = isbn
self.disponible = disponible
Libro.catalogo.append(self) Libro.prestamos[self.titulo]=0 self.popularidad = Libro.prestamos[self.titulo]def__str__(self):returnf"El libro {self.titulo}, del autor {self.autor}; disponibilidad: {self.disponible}"defcambiar_disponibilidad(self): self.disponible =not self.disponible
defprestar_libro(self):if self.disponible ==False:returnf"{self.titulo} no está disponible para prestarlo..." self.disponible =False Libro.prestamos[self.titulo]+=1 self.popularidad = Libro.prestamos[self.titulo]returnf"{self.titulo} ha sido prestado correctamente..."defdevolver_libro(self): self.disponible =Truereturnf"{self.titulo} ha sido devuelto correctamente..."defes_popular(self):returnf"¿{self.titulo} es popular? -> {Libro.prestamos[self.titulo]>=5}"
historial_prestamos =[]classLibro:def__init__(self, titulo, autor, isbn, disponible=True): self.titulo = titulo
self.autor = autor
self.isbn = isbn
self.disponible = disponible
defprestar(self):if self.disponible: historial_prestamos.append(self) self.disponible =Falsereturn(f"El titulo {self.titulo} fue prestado exitosamente")def__str__(self):returnf"Titulo: {self.titulo}, Autor: {self.autor}, ISBN: {self.isbn}, Disponibilidad: {self.disponible}"defdevolver(self): self.disponible =Truereturn(f"El titulo {self.titulo} fue devuelto exitosamente")defesPopular(self):if historial_prestamos.count(self)>5:return(f"El titulo {self.titulo} es popular")else:return(f"El titulo {self.titulo} no es popular")
Se me hace un poco inceficiente eso de usa una list a nivel de clase, yo creo vas a termina con una lista muy grande con datos muy similares, podrias agregar otro atributo a la clase libro y asi podrias consultado individualmente. Disculpa el comentario pero me dio curiosidad tu respuesta. Pero tu solucion si funciona.
En mi caso implementé un dict que guardara el isbn y la cantidad de veces que fue prestado. Este mismo se va a ver modificado cuando se llame set_lend debido a que llama a increment_lend lo que hace aumentar el contador de veces que fue prestado.
Para obtener el valor de si es popular o no implementé una función de get_lent_times el cual retorna la cantidad de veces que fue prestado y dentro de la clase Libro hay un método que devuelve un boolean en el caso de que dicha cantidad supere 5.
Agradezco comentarios.
books_lend_counter: dict[str, int]={"978-3-16-148410-0":5}def get_lend_times(isbn: str)-> int:return books_lend_counter.get(isbn,0)def increment_lend(isbn: str)->None: books_lend_counter[isbn]= books_lend_counter.get(isbn,0)+1classLibro: # Para poder agregar parametros a la clase se usa un método
def __init__(self,title: str,author: str,isbn: str,available: bool): self.title= title
self.author= author
self.isbn= isbn
self.available= available
def __str__(self)-> str:return f"Libro: {self.title} de {self.author} - ISBN: {self.isbn} - Disponible: {self.available}" def set_lend(self):if self.available: self.available=Falseincrement_lend(self.isbn)return f"'{self.title}' prestado exitosamente"return f"'{self.title} no está disponible para préstamo" def set_return(self): self.available=Truereturn f"'{self.title} devuelto y disponible nuevamente" def is_popular(self):returnget_lend_times(self.isbn)>5
les comparto mi solucion al ejercicio
libros_prestados =[]#defino el objetoclassLibro:def__init__(self, titulo, autor, isbn, disponible, prestado): self.titulo = titulo
self.autor = autor
self.isbn = isbn
self.disponible = disponible
self.prestado = prestado
def__str__(self):passdefprestar(self):if self.disponible: self.disponible =Falsefor prestado in catalogo_libros:if prestado["titulo"].lower()== self.titulo.lower(): prestado["veces_prestado"]+=1returnprint(f"\n'{self.titulo}' ah sido prestado")else:returnprint(f"\n'{self.titulo}' no disponible")defdevolver(self):ifnot self.disponible: self.disponible =Truereturnprint(f"\n'{self.titulo}' devuelto ")else:returnprint(f"\n{self.titulo} ya se encuentra en el inventario")catalogo_libros =[{"titulo":"Cien años de soledad","autor":"Gabriel García Márquez","isbn":"978-0307474728","disponible":True,"veces_prestado":12},{"titulo":"1984","autor":"George Orwell","isbn":"978-0451524935","disponible":False,"veces_prestado":5},{"titulo":"Orgullo y prejuicio","autor":"Jane Austen","isbn":"978-0141439518","disponible":True,"veces_prestado":4},{"titulo":"El resplandor","autor":"Stephen King","isbn":"978-0307743657","disponible":False,"veces_prestado":9},{"titulo":"Crónica de una muerte anunciada","autor":"Gabriel García Márquez","isbn":"978-1400034956","disponible":True,"veces_prestado":8},{"titulo":"El hombre más rico de Babilonia","autor":"George S. Clason","isbn":"978-1508524359","disponible":False,"veces_prestado":13}]#agrego un nuevo libro y lo agrego al listado de librosnuevo_libro = Libro("Este dolor no es mío"," Mark Wolynn","9788411082198",True,6)print(f"mi libro: {nuevo_libro.autor}, {nuevo_libro.titulo}, {nuevo_libro.isbn}, {nuevo_libro.disponible}, {nuevo_libro.prestado}")agregado ={"titulo": nuevo_libro.titulo,"autor": nuevo_libro.autor,"isbn": nuevo_libro.isbn,"disponible": nuevo_libro.disponible,"veces_prestado": nuevo_libro.prestado
}catalogo_libros.append(agregado)#pruebo que libros estan disponibles y cuales noprint("\nlibros disponibles: ")for libros in catalogo_libros:if libros["disponible"]:print(f" -{libros["titulo"]}")print("\nlibros sin stock: ")for libros in catalogo_libros:ifnot libros["disponible"]:print(f" -{libros["titulo"]}")#pido y devuelvo el mismo libro varias vecesfor i inrange(6): nuevo_libro.prestar() nuevo_libro.devolver()#muestro cual libro ha sido prestado mas vecesmas_prestado =""max_veces =-1for libro in catalogo_libros:if libro["veces_prestado"]> max_veces: max_veces = libro["veces_prestado"] mas_prestado = libro["titulo"], libro["veces_prestado"]#muestro el libro mas pedidoprint(f"\n{mas_prestado[0]} es el libro mas prestado con un total de {mas_prestado[1]} veces prestadas")
classLibro:def__init__(self, titulo, autor, isbn, disponible=True): self.titulo = titulo
self.autor = autor
self.isbn = isbn
self.disponible = disponible
self.prestamos =0def__str__(self):returnf"{self.titulo} por {self.autor} disponible: {self.disponible}"defprestar(self):if self.disponible: self.disponible =False self.prestamos +=1returnf"'{self.titulo}' prestado exitosamente"else:returnf"'{self.titulo}' no esta disponible"defdevolver(self):# Metodos son las funcionesifnot self.disponible: self.disponible =Truereturnf"'{self.titulo}' devuelto y disponible nuevamente"else:returnf"'{self.titulo}' no puede ser devuelto"defes_popular(self):return self.prestamos >=5mi_libro = Libro("Cien años de Soledad","Gabriel Garcia Marquez","55555",True)otro_libro = Libro("El principito","Saint-Exupéry","555555",True)otro_mas = Libro("Sapiens","Pedro Pipiales","555555",False)for _ inrange(5):print(mi_libro.prestar())print(mi_libro.devolver())print(mi_libro.prestar())print(mi_libro.devolver())print("¿Es popular?", mi_libro.es_popular())catalogo =[mi_libro, otro_libro, otro_mas]for libro in catalogo:print(libro)
classBook: def __init__(self, title, author, isbn, available=True): self.title= title
self.author= author
self.isbn= isbn
self.available= available
self.borrow_count=0 def __str__(self): available ="Available"if self.availableelse"Not Available"return f"{self.title}, {self.author}, {self.isbn}, {available}" def borrow_book(self):if self.available: self.available=False self.borrow_count+=1return f"The book {self.title} was borrowed successfully."else:return f"The book {self.title} is not available." def return_book(self):if not self.available: self.available=Truereturn f"The book {self.title} was returned successfully."else:return f"The book {self.title} can not be returned." def is_popular(self):return self.borrow_count>5book_1 =Book("100 Años de Soledad","Gabriel García Marquez","123")book_2 =Book("El Principito","Saint-Exupery","124")book_3 =Book("Kafka en le Orilla","Haruki Murakami","987",False)book_1.borrow_book()book_1.return_book()book_1.borrow_book()book_1.return_book()book_1.borrow_book()book_1.return_book()book_1.borrow_book()book_1.return_book()book_1.borrow_book()book_1.return_book()book_1.borrow_book()book_1.return_book()book_1.borrow_book()book_1.return_book()print(book_1.borrow_book())if book_1.is_popular():print( f"The book {book_1.title} is popular and has been borrowed {book_1.borrow_count} times.")catalogue =[book_1, book_2, book_3]for index, book inenumerate(catalogue, start=1):print(f"Book {index}:", book)
return f"{self.titulo}, por {self.autor}, {self.ISBN},disponible {self.disponible}"
def prestar(self):
if self.disponible:
self.disponible=False
return f"{self.titulo}' prestado exitosamente"
def devolver(self):
self.disponible=True
return f"{self.titulo}' el titulo ha sido devuelto y disponible nuevamente"
def es_popular(self ):
self.valor +=1
if self.valor >5:
return f"{self.titulo} es un libro popular"
return f"{self.titulo} aún no es popular"
mi_libro=Libro("Cien Años de Soledad","Daniela Fonseca",10002,True)
otro_libro=Libro("Perro come perro","Camilo Soracá", 10003,False)
libro_tres=Libro("El principito","Jose Ivan Soracá Zea",10004, False)
print("----------------------------------------")
for _ in range(6):
print(mi_libro.es_popular())
print("----------------------------------------")
catalogo=[mi_libro,otro_libro,libro_tres]
for libro in catalogo:
print(libro)
classLibro: def __init__(self, title, autor,isbn,available): self.title= title
self.autor= autor
self.isbn= isbn
self.available= available
self.prestamos=0 self.historial_prestamos=[] def __str__(self):return f"{self.title} - {self.autor} - {self.isbn} - {self.available}" def prestar(self,usuario):if self.available: self.available=False self.historial_prestamos.append((usuario)) self.prestamos+=1return f"El libro {self.title} ha sido prestado a {usuario}"else:return f"El libro {self.title} no esta disponible" def devolver(self,usuario):if not self.available: self.available=True self.historial_prestamos.append((usuario))return f"El libro {self.title} ha sido devuelto por {usuario}"else:return f"El libro {self.title} no esta disponible" def mostrar_historial(self):for prestamo in self.historial_prestamos:print(prestamo) def es_popular(self):iflen(self.historial_prestamos)>6:print(f"El libro {self.title} es popular")returnTruereturnFalselibro1 =Libro("El Principito","Antoine de Saint-Exupéry","978-84-9989-000-0",True)libro2 =Libro("Don Quijote de la Mancha","Miguel de Cervantes","978-84-9989-000-1",True)libro3 =Libro("Cien años de soledad","Gabriel García Márquez","978-84-9989-000-2",True)catalogo_libros =[libro1, libro2, libro3]visitantes=["Juan","Maria","Pedro","Ana","Luis"]for persona invisitantes: libro1.prestar(persona) libro1.devolver(persona) libro1.es_popular()print(f"El libro {libro1.title} tiene {libro1.prestamos} prestamos\n")print(f"El libro {libro2.title} tiene {libro2.prestamos} prestamos\n")print(f"El libro {libro3.title} tiene {libro3.prestamos} prestamos\n")