Область вложенных функций в Python - PullRequest
2 голосов
/ 02 марта 2010

У меня есть следующая функция, которая обходит вложенное дерево и печатает результат

def walk_tree(tree):   
    def read_node(node):
        print node
        for n in node['subnodes']:
            read_node(n)
    read_node(tree)

Если я хочу вернуть txt с данными, собранными при обходе дерева, подумал, что сработало бы следующее:

def walk_tree(tree):
    txt = ''  
    def read_node(node):
        txt += node
        for n in node['subnodes']:
            read_node(n)
    read_node(tree)

Но txt, похоже, не в сфере действия read_node. Любое предложение? Спасибо

Ответы [ 3 ]

6 голосов
/ 02 марта 2010

txt доступен в read_node, я думаю, что это просто какая-то проблема с += и что txt не входит в локальную область действия в read_node.

>>> def a():
...  x = ""
...  def b():
...   x += "X"
...  b()
...  print x
... 
>>> a()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in a
  File "<stdin>", line 4, in b
UnboundLocalError: local variable 'x' referenced before assignment
>>> 
>>> 
>>> def a():
...  x = []
...  def b():
...   x.append("X")
...  b()
...  print "".join(x)
... 
>>> a()
X

В любом случае вы должны использовать list и "".join(...) вместо str += ....

5 голосов
/ 02 марта 2010

В Python вы не можете перепривязывать переменные внешней области видимости (walk_tree в вашем примере).

Так что это не удастся:

def a():
    def b():
        txt += "b" # !!!

        print txt

    txt = "mytext"
    b()

a()

но это будет работать:

def a():
    def b():
        # removed assignment: txt += "b"

        print txt

    txt = "mytext"
    b()

a()

Так что вы можете избежать повторного связывания:

def a():
    def b():
        obj["key"] = "newtext"

    obj = {"key" : "mytext"}
    b()

a()
0 голосов
/ 02 марта 2010

Вы можете попробовать:

def walk_tree(tree):
    txt = ''  # (1)
    def read_node(node, txt=txt):
        txt += node # (2)
        for n in node['subnodes']:
            read_node(n, txt)
    read_node(tree)

Это связывает walk_tree s значение txt со значением по умолчанию в read_node, которое должно сохраняться (если мое понимание теории Python верно).

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