чистый функция — это функция, похожая на математическую функцию, в которой нет ни взаимодействия с «реальным миром», ни побочных эффектов. С более практической точки зрения это означает, что чистая функция не может не:
- Распечатать или иным образом показать сообщение
- Быть случайным
- Зависит от системного времени
- Изменить глобальные переменные
- И другие
Все эти ограничения облегчают рассуждения о чистых функциях, чем о нечистых. Тогда большинство функций должны быть чистыми, чтобы в программе было меньше ошибок.
В языках с огромной системой типов, таких как Haskell, читатель с самого начала может знать, является функция чистой или нет, что облегчает последующее чтение.
В Python эта информация может эмулироваться декоратором @pure
, помещенным поверх функции. Я также хотел бы, чтобы этот декоратор действительно выполнял некоторую работу по проверке. Моя проблема заключается в реализации такого декоратора.
Прямо сейчас я просто просматриваю исходный код функции на наличие таких модных словечек, как global
, random
или print
, и жалуюсь, если находит одно из них.
import inspect
def pure(function):
source = inspect.getsource(function)
for non_pure_indicator in ('random', 'time', 'input', 'print', 'global'):
if non_pure_indicator in source:
raise ValueError("The function {} is not pure as it uses `{}`".format(
function.__name__, non_pure_indicator))
return function
Однако это похоже на странный хак, который может сработать или не сработать в зависимости от вашей удачи, не могли бы вы помочь мне написать лучший декоратор?
inspect.getsource
затемast.parse
и пройтись по узлам, проверяя разные вещи... но вы пойдете против причины, по которой существует язык - посмотрите на использование модуляabc
, если хотите что-то, а затемisinstance
проверьте, где это необходимо... - python строго типизирован, а не статически типизирован - person Jon Clements♦   schedule 22.07.2015__dunder__
методов и других функций. Каждый из этих вызовов может делать что угодно, от изменения практически любого объекта до изменения того, какие функции будут вызываться в следующей строке. Неполный черный список — это лучшее, что вы можете сделать, но это также можно сделать статически с помощью линтера, без необходимости проверки во время выполнения. - person   schedule 22.07.2015__globals__
< функции /a>, но не рекомендуется. Честно говоря, просто изучите Haskell. - person NightShadeQueen   schedule 22.07.2015