es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo obtener el nombre de un atributo como cadena en Python.

Quiero recuperar el nombre del atributo para crear algo como un “puntero” en Python, por ahora uso la siguiente declaración pero no estoy satisfecho:

class foo:
   name: str
   last_name: str

class other:
   def __init__(self, obj, var):
        obj.__dict__[var] = "John"

f = foo("Jon", "Jon")
o = other(f, "name")

Quiero escribir:

o = other(f, f.name)

o mejor aún

o = other(f.name)

Intenté algunas funciones para obtener el nombre pero solo funcionan con objetos y no con atributos de objetos:

def retrieve_name(var: object) -> str:
    for objname, oid in globals().items():
        if oid is var:
            return objname
        if hasattr(oid, "__dict__"):
            for child in oid.__dict__:
                # no funciona porque el id es el mismo si el valor es el mismo
                if id(oid.__dict__[child]) == id(var):
                    return child

Este código solo funciona si uso retrieve_name(f) -> f pero no si uso retrieve_name(f.last_name) -> name si f.name == f.last_name porque id(f.name) == id(f.last_name) cuando los valores de las cadenas son iguales.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para recuperar el nombre del atributo y usarlo para crear un puntero en Python, puedes modificar la clase other para que acepte tanto el objeto como el nombre del atributo como argumentos en el constructor. Luego, puedes usar la función getattr() para recuperar el valor del atributo del objeto utilizando el nombre del atributo. Aquí tienes un ejemplo de código:

    class foo:
        name: str
        last_name: str
    
    class other:
        def __init__(self, obj, attr_name):
            setattr(self, attr_name, getattr(obj, attr_name))
    
    f = foo("Jon", "Doe")
    o = other(f, "name")
    print(o.name)  # Output: Jon
    

    En este ejemplo, la clase other almacena el valor del atributo en una variable de instancia con el mismo nombre que el atributo. Luego puedes acceder al valor utilizando la notación de puntos (o.name).

    Si quieres crear un comportamiento similar a un puntero en Python, puedes usar los decoradores @property y @setter para definir los getters y setters del atributo. Aquí tienes un ejemplo de código actualizado:

    class foo:
        def __init__(self, name, last_name):
            self._name = name
            self._last_name = last_name
    
        @property
        def name(self):
            return self._name
    
        @name.setter
        def name(self, value):
            self._name = value
    
        @property
        def last_name(self):
            return self._last_name
    
        @last_name.setter
        def last_name(self, value):
            self._last_name = value
    
    
    class other:
        def __init__(self, obj, attr_name):
            self._obj = obj
            self._attr_name = attr_name
    
        @property
        def value(self):
            return getattr(self._obj, self._attr_name)
    
        @value.setter
        def value(self, new_value):
            setattr(self._obj, self._attr_name, new_value)
    
    
    f = foo("Jon", "Doe")
    o = other(f, "name")
    print(o.value)  # Output: Jon
    o.value = "Jane"
    print(f.name)   # Output: Jane
    

    En este ejemplo actualizado, la clase foo define _name y _last_name como variables de instancia privadas y usa los decoradores @property y @setter para definir name y last_name como getters y setters respectivamente. La clase other almacena el objeto y el nombre del atributo como variables de instancia y define value y value.setter como getters y setters respectivamente, usando getattr() y setattr() para recuperar y establecer el valor del atributo. Luego puedes usar las instancias de la clase other como punteros al valor del atributo de las instancias de la clase foo.

Comments are closed.