Рубрики
Без рубрики

Насмешка, добавляя атрибуты к функциям

Функции Python являются первоклассными объектами, что означает, что мы можем прикрепить все данные, которые хотим на них!. Tagged с Python.

Я читал пост в блоге о том, как быстро издеваться над функцией печати, чтобы проверить вывод функции в командную строку, и я наткнулся на эту технику.

def fake_print(*args, sep=" ", end="\n"):
    fake_print.output.append(sep.join(args) + end)

fake_print.output = []

mymodule.print = fake_print

mymodule.run_function()

expected = """Hello there.
How are you?
I'm great, thanks!
Banana.
"""

assert expected == "\n".join(fake_print.output) + "\n"

Итак, во-первых, я знаю, что есть лучшие и более надежные способы сделать это. У меня есть пост в моем списке проектов, чтобы сделать с этим. И я также знаю, что в целом, если вам нужно проверить Stdout, чтобы убедиться, что ваша функция работает правильно, есть разумная вероятность, что вы сможете лучше структурировать свой код и облегчить тестирование. В этом случае классовое назначение заставило меня выполнять некоторые операции, и я собирался быть оценен, точно ли мой выход STDOU Я сделал глупую ошибку печати.

В любом случае, я вхожу в путь. точка этого поста таково:

Я знаю, что функции являются объектами. Вы все время слышите, что они «первоклассные» объекты (что означает, что они получают лучшие закуски, и их места откидываются). Я передал их в качестве аргументов, присвоил им переменные, определил их внутри других функций и возвращал их.

Я никогда не думал о том, что, поскольку они являются объектами, вы можете придерживаться их произвольных свойств, когда захотите!

Теперь. Разумный следующий вопрос: это хорошая идея? Насколько это полезно? Мой ответ: Наверное, не так уж и много.

Реально, все, что вы здесь делаете, – это осторожно скрывать то, что может быть глобальной переменной внутри свойств этой функции. Вы добавляете хорошую самостоятельную документацию того, что делает эта переменная, делая это? Может быть. Вы очищаете глобальное пространство имен? Конечно. Но по большей части он пахнет немного «умным в плохом смысле».

Как я уже сказал, я программировал Python в течение трех или четырех лет и наставничество, по крайней мере, один, и я никогда видел это. Это никогда мне пришло в голову. Я ли я конечный арбитр Guru Guru Guru Guru? Нет. (Хорошо, иногда я говорю своей кошке.) Но это кажется хорошим показателем, что это не совсем обычное явление. И я не думаю, что небольшие, аккуратные преимущества размещения имен и маленький хихиканье, которое я получаю от умного, стоят умственных накладных расходов любого другого, кто должен читать мой код.

Тем не менее, с учетом всего этого, это все еще аккуратный трюк и выделяет некоторые вещи, которые я люблю в Python в целом. Вот еще один пример использования, чтобы показать это: кэширование.

def fibonacci(n):
    if n in fibonacci.cache:
        return fibonacci.cache[n]

    result = fibonacci(n - 1) + fibonacci(n - 2)
    fibonacci.cache[n] = result
    return result

fibonacci.cache = {}

Это сохраняет кучу вызовов функций, сохраняя результаты вычислений в кэш диктат

Примечание: Это действительно просто хромая версия functools.lru_cache . Поищи это. Это здорово!

В любом случае, я просто хотел поделиться этим аккуратным, странным способом обработки чего -либо в Python. Спасибо за чтение!

Оригинал: “https://dev.to/rpalo/mocking-by-adding-attributes-to-functions-5ae0”