Ваши примеры - это реальный код или просто примеры?
Если это реальный код, я думаю, что вы злоупотребляете декораторами, возможно, из-за вашего прошлого (то есть вы привыкли к другим языкам программирования)
Этап 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
Этот метод запуска устарел makeRunner. Ваш пример превращается в:
def pp(n): print "%s," % n.val
run(tree, pp)
Однако это полностью игнорирует генераторы, поэтому…
Этап 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)