SyntaxError в Python-декораторах - PullRequest
1 голос
/ 07 июня 2019

Почему следующий фрагмент кода Python:

def f():
    def g():
        def h(x):
            pass
        return h
    return g

@f()()
def i():
    pass

поднимает SyntaxError?

    @f()()
        ^
SyntaxError: invalid syntax

Потому что, как я понимаю, декоратор является вызываемым с единственным обязательным позиционным параметром, то есть это допустимые декораторы:

def f(x):
    pass

def g(x, y=3):
    pass

class A:
    def __init__(self, x):
        pass

class B:
    def __init__(self, x, y=3):
        pass

И они используются как:

def h():
    pass

h = f(h)
h = g(h)
h = A(h)
h = B(h)

class C:
    pass

C = f(C)
C = g(C)
C = A(C)
C = B(C)

или с помощью оператора @expression, где expression должен вычисляться для декоратора, за которым должно следовать определение функции или класса или другой оператор @expression:

@f
def h():
    pass

@g
def h():
    pass

@A
def h():
    pass

@B
def h():
    pass

@f
class C:
    pass

@g
class C:
    pass

@A
class C:
    pass

@B
class C:
    pass

Следующее @expression утверждение совершенно верно:

def f():
    def g():
        def h(x):
            pass
        return h
    return g

def g(x):
    def h(x):
        pass
    return g

@g(f()())
def h():
    pass

так почему же вверху нет?

1 Ответ

2 голосов
/ 07 июня 2019

Поскольку это синтаксическая ошибка, мы должны перейти к грамматике:

decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE

Часть после @ не является произвольным выражением;это одно имя с одним необязательным списком аргументов.

Я понимаю, что это не отвечает на вопрос почему грамматика написана таким образом, но я нелюбой ответ, кроме "Так оно и есть".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...