Я пытался разработать библиотеку python для использования монадов (игрушечный проект, чтобы понять как монады, так и то, как python может действовать как «чисто функциональный» язык), но этот вопрос не имеет ничего общего с монадами или функциональным программированием.Класс декоративного декоратора Python, демонстрирующий странное поведение
В необходимости оператора сочинить функции, я попытался следующий «декоратора класс»:
class Composable(object):
def __init__(self, func):
self._func = func
def __call__(self, *args):
return self._func(*args)
def _compose(self, func):
@Composable
def _func(*args):
return func(self._func(*args))
return _func
def __mul__(self, func):
return self._compose(other)
Он должен быть использован как внутри метода «_compose», и она работает безупречно, если я использую его для «орфографической функции». То есть, следующий код работает отлично:
@Composable
def function1(n):
return n + 1
@Composable
def function2(n):
return n * 2
print((function1 * function2)(5)) #outputs (5 * 2) + 1 = 11
Дело в том, что я не понимаю, что, если я украсят две функции декораторы с «наборный», я не буду иметь возможность непосредственно создавать их в качестве декораторов , используя «умножение» оператор, как я делал раньше:
@Composable
def decorator1(func):
def decorated(n):
return func(n) + 1
return decorated
@Composable
def decorator2(func):
def decorated(n):
return func(n) * 2
return decorated
#This triggers a "SyntaxError" (with or without enclosing parentheses)
@decorator1 * decorator2
def function(n):
return n
#While this works fine
@decorator1._compose(decorator2)
def function(n):
return n
#Not quite surprisingly, this works fine too
@decorator1.__mul__(decorator2)
#(as always, this outputs (5 * 2) + 1 = 11)
function(5)
Мой пункт: я «было сказано» (см the mul magic method и python decorators), что
a * b
не так много мо повторно чем синтаксический сахар для
a.__mul__(b)
и что
@decorator
def f(n):
pass
это не более чем
def f(n):
pass
f = decorator(f)
Так вот мой вопрос: что здесь происходит? Не являются ли декораторы результатом оценки любого выражения, которое возвращает вызываемый?
Да, и если кто-нибудь задавался вопросом: я использую python3.5
Я не думаю, что '@ decorator1' в' @ decorator1 * decorator2' является объектом. –
Вы смешиваете соль в синтаксическом сахаре! Нет, вы не можете размножать декораторы при использовании синтаксиса '@'; вы можете увидеть [в ссылке на язык] (https://docs.python.org/3/reference/compound_stmts.html#function-definitions), что это не юридическая грамматика. – jonrsharpe
См. Также [PEP 318] (https: //www.python.org/dev/peps/pep-0318/# id30): «Утверждение декоратора ограничено тем, что он может принять, - произвольные выражения не будут работать» –