Stack Overflow en español Asked on December 20, 2021
Teniendo el siguiente código:
class Usuarios:
def __init__(self,nombre,genero,edad):
self.nombre = nombre
self.genero = genero
self.edad = edad
def funcion(self):
list = []
if self.genero == "Femenino":
list.append(Objeto)
print("Femeninon", list)
elif self.genero == "Masculino":
list.append(Objeto)
print("Masculinon", list)
else:
print("Ha ocurrido un error")
Estoy intentando añadir el valor del objeto en texto a la lista, en este caso ("Juan", "Masculino", "30")
.
Objeto = Usuarios("Juan", "Masculino", "30")
Objeto.funcion()
Cuando ejecuto el código imprime la ubicación del objeto, por lo que no sé si estoy agregando alguna información a la lista
Gracias.
En Python todo son objetos, hasta los tipos de datos nativos son objetos. Estos cuentas con atributos y métodos implementados. Cuando se está generando un objeto a través de la instancia de una clase, se puede decir que se está definiendo un tipo de dato personalizado.
Este objeto tiene un comportamiento predefinido, con la definición de sus atributos y métodos que hacen uso de sus atributos. Esto al igual que todos los elementos del programa, requiere de espacio en memoria.
La diferencia de los tipos de datos nativos y este tipo de dato personalizado, es que los primeros cuentan con una representación formal en el lenguaje.
Un objeto definido, no cuenta con la representación oficial de una expresión valida de Python.
Veamos dos métodos mágicos, que se pueden definir en la definición de una clase:
object.__str__()
Según su referencia en la documentación:
Called by str(object) and the built-in functions format() and print() to compute the “informal” or nicely printable string representation of an object. The return value must be a string object.
This method differs from object.repr() in that there is no expectation that str() return a valid Python expression: a more convenient or concise representation can be used
Traduciendo el segundo parrafo:
Este método es distinto a
__repr__()
, debido a que no se espera que el método__str__
devuelva una expresión válida en Python.
Esto significa que
El método es llamado cuando se usa el objeto como argumento en las funciones format()
,print()
y str()
.
Define una representación informal para representar el valor del objeto como string
Esto se puede verificar definiendo __str__()
en un clase:
class Clase:
def __init__(self,atributo):
self.atributo = atributo
def __str__(self):
return "Objeto con el atributo {}".format(self.atributo)
Si se usa intenta hacer un conversión de string con un objeto generado por esta clase, ya sea con print()
, format()
o str()
. Esta conversión va tener como resultado el valor retornado por __str__()
.
Objeto = Clase("foo")
print("Valor del objeto:",Objeto)
mostraría
Valor del objeto: Objeto con el atributo foo
¿Por que se dice que esto es una representación informal?
Debido a que esta representación solo es válida a la hora realizar una coversión a string. Si se intentara representar de otra manera se obtendría esa "dirección en memoria", que en realidad es la descripción prredeterminada.
lista_de_objetos = [Objeto]
print(lista_de_objetos)
mostraría
[<__main__.Clase object at 0x000001FC65AE60D0>]
El método __str__()
no define la representación formal de un objeto.
object.__repr__()
Según su referencia en la documentación:
Called by the repr() built-in function to compute the “official” string representation of an object. If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment).
If this is not possible, a string of the form
<...some useful description...>
should be returned. The return value must be a string object. If a class defines repr() but not str(), then repr() is also used when an “informal” string representation of instances of that class is required.
Traduciendo un fragmento del primer parrafo:
Se llama la función
repr()
para definir la representación "oficial" de un objeto. Si es posible debería de lucir como una expresión válida de Python.
Traduciendo un fragmento del segundo parrafo:
Si no es posible, se representará con un string en la forma
<... información útil ...>
¿Que hace la función repr()
?
Retorna la representación formal de un objeto en formato de string, cuando se dice objeto se habla de variables, valores retornados por funciones, etc...
variable = "Mango"
print(repr(variable))
mostaría
'Mango'
Ahora, si se define el método __repr__()
en una clase, se puede definir cuál va a ser esta salida.
class Clase:
def __init__(self,atributo):
self.atributo = atributo
def __repr__(self):
return "Soy un {}".format(self.atributo)
Siguiendo las indicaciones de la especificación en la documentación:
The return value must be a string object.
Ahora el objeto no solo es representado a la hora de usarse como string:
objeto_mango = Clase("Mango")
print(objeto_mango)
mostraría:
Soy un Mango
Cualquier representación es válida:
lista_objetos = [objeto_mango]
print(lista_objetos)
mostraría:
[Soy un Mango]
Esto es lo que se considera como una representación formal.
¿Por qué razón cuando intento imprimir una variable se imprime su dirección en memoria y no su valor?
Es debido a que cuando intentas imprimir la lista que contiene el objeto, este objeto no cuenta con una representación formal si no con la representación predeterminada o bien "la dirección de memoria".
Cuando ejecuto el código imprime la ubicación del objeto
Hay otro errores en tu código
Veamos la expresión
list.append(Objeto)
Esto implica añadir a una lista dentro del propio objeto al objeto.
Objeto => contiene => |list_ = [Objeto]|
Nota:* Aquí se cambia el nombre de list
por list_
, debido a que list
es una palabra reservada del lenguaje y esto puede generar problemas.
Objeto => contiene => |list_ = [Objeto]|
Se está instanciando un objeto como parte del mismo objeto, esto sería válido si se hiciera de la manera adecuada.
Por que no se está definiendo un un nuevo objeto que forme parte de otro objeto de la misma clase, si no que el mismo objeto esta definido con un objeto.
No se puede definir algo con algo, ya que algo no está definido.
¿Cuál es la manera adecuada de instanciar objetos dentro de otro objeto con la misma clase?
Generando un objeto nuevo
self.list_.append(Usuarios(self.nombre,self.genero,self.edad))
Cuando se crea un objeto como este
usuario1 = Usuarios("Juan", "Masculino", "30")
Los parámetros pasán a __init__()
y pasan a instanciarse como atributos de la clase. Esto permite que los métodos de dicha clase tengan acceso nativo a estos parámetros. Al generarse una nuevo objeto con los atributos de la clase, se está generando un objeto con los mismo parámetros que se inicializó la clase.
objeto = Clase(arg0, arg1) #Objeto inicial
^ ^
| |
* *
__init__(self,arg0,arg1)
^ ^
| |
* *
funcion() => Clase(arg0,arg1) #Objeto nuevo
El objeto inicial, puede almacenar otro objeto distinto a este mismo.
Hablando de ámbitos, es necesario instancia a list_
como atributo de la clase. De esta manera tiene ámbito global implícito sobre todos los métodos de esta misma clase, y valor perdura en el objeto que se inicialize
self.list_ = []
por lo que no sé si estoy agregando alguna información a la lista
Al definir la representación del objeto, podemos visualizar este objeto y ver si se está agregando información a list_
def __repr__(self):
return "Objeto: ({}, {}, {})".format(self.nombre,self.genero,self.edad)
Al invocar el método de la clase funcion()
y imprimir el valor actual de del objeto generado
usuario1 = Usuarios("Juan", "Masculino", "30")
usuario1.funcion()
print(usuario1)
Podemos ver que sí, el objeto está en la lista!
Masculino
[Objeto: (Juan, Masculino, 30)]
Objeto: (Juan, Masculino, 30)
Espero todo te haya quedado claro.
Answered by user166844 on December 20, 2021
No se si esto es lo que quieres:
class Usuarios:
def __init__(self, nombre, genero, edad):
self.nombre = nombre
self.genero = genero
self.edad = edad
def __repr__(self):
return "Usuarios(nombre={}, genero={}, edad={})".format(self.nombre, self.genero, self.edad)
Objeto = Usuarios("Juan", "Masculino", "30")
print(Objeto)
Cuando imprimes un objeto, por defecto te retorna la dirección de memoria donde ha sido instanciado por la clase. Sin embargo, existen los metodos "str" y "str" que son invocados cuando consultas una variable o cuando la imprimes. Si no se define el método "str", el método "repr" toma el control de ambas acciones. Asi que ahora cuando imprimas un objeto se mostrará la cadena generada en el método "repr".
Cuando en consola escribes (considerando que hay un objeto instanciado llamado "obj"):
ojb <ENTER>
Se invoca a __repr__
Cuando en consola escribes:
print(obj) <ENTER>
Answered by Luis Munoz on December 20, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP