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.

Usando decoradores en Python para recopilar información sobre los métodos disponibles y almacenar esos datos en la clase o instancia.

Encontré muchas preguntas relacionadas con los decoradores y las clases, y el acceso a la instancia de clase que está siendo decorada. Según pude entender, el generador de decoradores no puede acceder a la instancia del objeto porque, en ese momento, aún no se ha creado ningún objeto.

Sin embargo, parece que si un decorador utiliza una referencia de clase (me refiero a que recibe cls), entonces puedo acceder a algunos campos de clase:

class Foo:
    _tags = {}

    @classmethod
    def _tag(cls, tag_name):
        def decorator(func):
            def tmp(*args, **kwargs):
                return func(*args, **kwargs)

            cls._tags[tag_name] = func.__name__
            return tmp

        return decorator

Esto funciona de maravilla para las subclases, donde puedo escribir:

@Foo._tag("something")
def somethingelse():
    pass

Pero esto almacena la información en la clase padre (como era de esperar), ya que estamos hablando de variables de clase.

Me pregunto si hay alguna manera de tener un comportamiento similar, pero garantizando que cada subclase tenga su propia instancia de la propiedad _tags.

Puedo anticipar algunos métodos alternativos, como analizar el código fuente o inspeccionar las funciones durante __init__. Pero estaba buscando una forma más sencilla, si existe una.

Edit 1: para que quede más claro, quiero decorar métodos de la subclase. Por lo tanto, esto no es una posibilidad:

class Bar(Foo):
    @Bar._tag("method")
    def method(self):
        pass

ya que el procesador/compilador aún no ha completado la creación de la clase. De lo contrario, la solución propuesta de un diccionario de dos niveles con clase/método funcionaría lo suficientemente bien para mí.

SOLUCIÓN ALTERNATIVA

Mi decorador:

@classmethod
def TAG(cls, name):
    def decorator(func):
        def tmp(*args, **kwargs):
            return func(*args, **kwargs)

        tmp._has_alias = name
        return tmp
    return decorator

Durante __init__, obtengo esta información y la almaceno:

self._tags = {getattr(self, name)._has_alias: name for name in dir(self) if callable(getattr(self, name)) and hasattr(getattr(self, name), "_has_alias")}
Tags:  ,

Answer

  1. Avatar for davy.ai

    La pregunta se trata sobre los decoradores en Python y su acceso a las instancias de clase. Se afirma que los generadores de decoradores no pueden acceder a las instancias de los objetos ya que aún no se ha creado ningún objeto. Sin embargo, el uso de una referencia de clase en un decorador puede proporcionar acceso a algunos campos de clase.

    Se proporciona un código de ejemplo que utiliza un método de clase y un decorador para almacenar información en variables de clase. La pregunta es si hay alguna manera de asegurarse de que cada subclase tenga su propia instancia de la propiedad _tags.

    La solución propuesta por el autor es utilizar un decorador con un nombre de etiqueta que se almacena en el atributo _has_alias de la función. Durante __init__, esta información se recupera y se almacena en un diccionario específico para la instancia de la clase.

Comments are closed.