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.

Clase no reconocida en los argumentos del decorador.

Pasando una variable de clase como argumento para una función decoradora, conduce a un error de nombre (NameError) para el nombre de la clase. Ejecutando esto:

def log(prefix=None):

    def decorator(function):
        """Decorates the function"""

        def wrapper(*args, **params):
            """Wraps the function"""
            name = "-".join([prefix, function.__name__])

            result = function(*args, **params)
            print(f"completed the execution of '{name}'")
            return result

        return wrapper

    return decorator


class ExampleClass:

    _CONSTANT = "test"

    def __init__(self, x):
        self._x = x

    @log(prefix=ExampleClass._CONSTANT)
    def product_of_number(self, y):
        return self._x * y

if __name__ == "__main__":
    x = ExampleClass(3)
    x.product_of_number(4)

Conduce al siguiente error:

Traceback (most recent call last):
  File "/home/developer/reproduce_decorator_namespace.py", line 23, in <module>
    class ExampleClass:
  File "/home/developer/reproduce_decorator_namespace.py", line 31, in ExampleClass
    @log(prefix=ExampleClass._CONSTANT)
NameError: name 'ExampleClass' is not defined

Sin embargo, ejecutando esto:

def log(prefix=None):

    def decorator(function):
        """Decorates the function"""

        def wrapper(*args, **params):
            """Wraps the function"""
            name = "-".join([prefix, function.__name__])

            result = function(*args, **params)
            print(f"completed the execution of '{name}'")
            return result

        return wrapper

    return decorator


_CONSTANT = "test"

class ExampleClass:

    def __init__(self, x):
        self._x = x

    @log(prefix=_CONSTANT)
    def product_of_number(self, y):
        return self._x * y

if __name__ == "__main__":
    x = ExampleClass(3)
    x.product_of_number(4)

Da como resultado:

completed the execution of 'test-product_of_number'

¿Por qué ExampleClass no es reconocido? El método decorado está dentro de la clase después de __init__ y hace referencia a self. El mensaje de error en sí se refiere al módulo ExampleClass. ¿Cómo es posible que el nombre de la clase no exista en el espacio de nombres?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Cuando se pasa ExampleClass._CONSTANT como argumento de la función decoradora log, la clase ExampleClass aún no ha sido definida. Por lo tanto, el nombre ExampleClass aún no está en el espacio de nombres cuando se aplica el decorador, lo que lleva al NameError.

    En el segundo ejemplo, _CONSTANT está definido fuera del alcance de la clase ExampleClass, por lo que está en el espacio de nombres cuando se aplica el decorador.

    Para evitar este problema, puedes definir la constante fuera de la clase o usar una cadena en lugar de una variable de clase para establecer el argumento prefix de la función decoradora.

Comments are closed.