Назад к подготовке

Вопрос про production ML

Write and explain a function decorator that logs calls. What does functools.wraps preserve? How would a decorator with arguments lazily import modules only when the function is called?

Ответить самому

Сначала сформулируйте ответ как на собеседовании, затем откройте разбор и оцените себя.

Загрузка

Короткий ответ

A decorator returns a wrapper around the original function. functools.wraps preserves metadata such as __name__ and __doc__. A decorator with arguments adds one more closure layer and can import modules inside the wrapper.

Полный разбор

A basic decorator accepts a function and returns another callable. The wrapper receives *args and **kwargs, can log inputs, calls the original function, logs the result, and returns it. functools.wraps(func) should decorate the wrapper so tooling, debugging and introspection still see the original function name, docstring, annotations and __wrapped__ link.

A decorator with arguments has three layers: the outer factory receives configuration, the middle decorator receives the function, and the inner wrapper receives runtime arguments. For lazy imports, the wrapper can call importlib.import_module(name) only at invocation time, optionally cache the module objects in the closure, and then call the original function.

The production nuance is that lazy import changes error timing and can hide import failures until runtime. Use it when startup cost matters, and make the behavior explicit.

Теория

Decorators are closures over callables; decorator factories add a configuration closure.

Типичные ошибки

  • Forget to return the wrapper.
  • Forget *args and **kwargs.
  • Skip functools.wraps and break introspection.

Как отвечать на собеседовании

  • Draw the three layers for a decorator with arguments.
  • Mention importlib.import_module for dynamic import by string name.