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.

Eres un traductor de español que traduce documentos de TI. Traduce lo siguiente al español. Escribe un decorador de Python dentro de una clase abstracta y úsalo en una clase heredada.

TL;DR: Quiero ejecutar alguna lógica (como actualizar una base de datos) dentro de una clase abstracta. Quizás haya otra forma de hacerlo, pero lo único que se me ocurre es usar un decorador.

Tengo la siguiente clase abstracta:

class MyAbstractClass(metaclass=abc.ABCMeta):

    @abc.abstractmethod
    def my_abstract_method(self, request):
        pass

    @staticmethod
    def decorator_func(self, func):
        def run_func(param_one, param_two):
            print('DENTRO DE run_func', param_one, param_two)
            results = self.update_database(param_one, param_two)
            func(test_id, request)
            print('FINALIZADO run_func')

        return run_func

    def update_database(self, param_one, param_two):
        results = <realizar algunas="" operaciones="" en="" el="" backend="">
        return results

Quiero crear una clase hija que herede de esta clase, y utilizar el método decorator_func para actualizar la base de datos en el método abstracto my_abstract_method:

class ChildClass(MyAbstractClass):
    def __init__(self):
        super().__init__()

    @MyAbstractClass.decorator_func
    def my_abstract_method(self, request):
        obtener_datos()

Sé que my_abstract_method obtendrá datos actualizados porque el decorador se aseguró de ejecutar update_database antes.

He intentado muchas combinaciones (como eliminar el @staticmethod o intentar aplicarlo con @classmethod) pero no funciona. Con el código actual, obtengo el error: run_func() recibe 2 argumentos posicionales pero se le pasaron 3.

¿Alguna idea de cómo puedo ejecutar fácilmente update_database antes de que se ejecute my_abstract_method?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece que estás intentando usar un decorador para actualizar una base de datos antes de ejecutar un método abstracto en una clase hija que hereda de una clase abstracta. Sin embargo, tu implementación actual del decorador está causando un error.

    Una posible solución es modificar la función del decorador y agregar un parámetro extra a ella. Este parámetro te permitirá pasar la instancia de la clase hija al decorador, que luego puede llamar al método update_database.

    Aquí tienes un ejemplo de implementación de la función decoradora modificada:

    class MyAbstractClass(metaclass=abc.ABCMeta):
    
        @abc.abstractmethod
        def my_abstract_method(self, request):
            pass
    
        @staticmethod
        def decorator_func(func):
            def run_func(self, request):
                print('DENTRO de run_func', request)
                results = self.update_database()
                func(self, request)
                print('TERMINADO run_func')
    
            return run_func
    
        def update_database(self):
            results = <hacer cálculos="" en="" el="" backend="">
            print('BASE DE DATOS ACTUALIZADA')
            return results
    
    
    class ChildClass(MyAbstractClass):
        def __init__(self):
            super().__init__()
    
        @MyAbstractClass.decorator_func
        def my_abstract_method(self, request):
            print('EJECUTANDO my_abstract_method')
    
    
    child = ChildClass()
    child.my_abstract_method('test')
    

    En este ejemplo, la función run_func toma dos parámetros (self y request). self se refiere a la instancia de la clase hija que está llamando a la función decoradora. Dentro de run_func, puedes llamar a self.update_database() para actualizar la base de datos antes de llamar a func(self, request), que ejecutará el método abstracto original.

    Ten en cuenta que también eliminé los parámetros param_one y param_two de run_func, ya que no se estaban utilizando en tu código de ejemplo.

    ¡Espero que esto te ayude! Házmelo saber si tienes alguna pregunta.

Comments are closed.