Почему декораторы Python, а не закрытия?

15
задан interstar 15 November 2008 в 00:59
поделиться

2 ответа

В то время как это верно, что синтаксически, декораторы являются просто "сахаром", который не является лучшим способом думать о них.

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

Это позволяет Вам использовать декораторов, чтобы сделать аспектно-ориентированное программирование (AOP). Таким образом, Вы хотите использовать декоратора, когда у Вас есть сквозная озабоченность, что Вы хотите инкапсулировать в одном месте.

наиболее существенный пример, вероятно, зарегистрировался бы, где Вы хотите зарегистрировать запись или выход функции или обоих. Используя декоратора эквивалентно применению совета (зарегистрируйте это!) к joinpoint (во время записи метода или выхода).

художественное оформление Метода является понятием как понимания списка или ООП. Как Вы указываете, это является не всегда соответствующим, и может злоупотребиться. Но в правильном месте, это может быть полезно для того, чтобы сделать код более модульным и отделенным.

13
ответ дан 30 November 2019 в 22:02
поделиться

Является Вашими примерами реальный код или просто примеры?

, Если они - реальный код, я думаю, что Вы злоупотребляете декораторов, вероятно, из-за Вашего образования (т.е. Вы привыкли к другим языкам программирования)

Этап 1: уход от декораторов

def run(rootnode, func):
    def _run(node): # recursive internal function
        func(node)
        for x in node.children:
            _run(x) # recurse
    _run(rootnode) # initial run

Этот метод obsoletes makeRunner выполнения. Ваш пример обращается к:

def pp(n): print "%s," % n.val
run(tree, pp)

Однако это игнорирует полностью генераторы, so†¦

Этап 2: использование генераторов

class Node :
    def __init__(self,val,children) :
        self.val = val
        self.children = children

    def __iter__(self): # recursive
        yield self
        for child in self.children:
            for item in child: # recurse
                yield item

def run(rootnode, func):
    for node in rootnode:
        func(node)

Ваш пример остается

def pp(n): print "%s," % n.val
run(tree, pp)

Примечание, которое специальный метод __iter__ позволяет нам использовать эти for node in rootnode: конструкция. Если Вам не нравится он, просто переименуйте __iter__ метод к, например, walker и изменитесь run цикл в: for node in rootnode.walker():
, Очевидно, эти run функция могла быть методом class Node вместо этого.

, Как Вы видите, я предлагаю, чтобы Вы использовали непосредственно run(tree, func) вместо того, чтобы связать их с именем printTree, но можно использовать их в декораторе, или можно использовать эти functools.partial функция:

printTree= functools.partial(run, func=pp)

и с тех пор, Вы были бы всего

printTree(tree)
8
ответ дан 30 November 2019 в 22:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: