使用python访问父级调用的子函数中的父函数变量

时间:2016-11-18 23:09:12

标签: python

在Python 3.4中,我想调用在父函数之外定义的子函数,该函数仍然可以访问父函数的范围(参见下面的示例)。虽然我在下面的示例中将函数parent和child命名为易于查看,但我正在考虑的函数具有非常独立的任务,并且单独定义它们更有意义。我习惯于在JavaScript中常常执行以下操作:

def parent():
    test = 0
    child()

def child():
    test += 1
    print(test)

但是,我在执行上面的代码时只是出错了。我尝试使用' nonlocal'关键字也失败了:

def parent():
    test = 0
    child()

def child():
    nonlocal test
    test += 1
    print(test)

错误消息是“非本地”'测试'发现&#39 ;.这在python中是否可行,因为它在许多其他语言中,或者是以下(不是首选)的唯一选项:

def parent():
    test = 0

    def child():
        nonlocal test
        test += 1
        print(test)

    child()

编辑:将父变量传递给子函数不能在我的用例中工作,因为我需要修改父变量。

编辑2:父方法和子方法已经是一个在逻辑上没有计数器属性的类的一部分。计数器是两个函数内部的东西,用于跟踪图形中的节点访问(参见下面的实例):

class Graph():
    def depthFirstSearch(self):
        for vertex in self.adjacency_list:
            vertex.status = "not visited"
            vertex.previous = None

        visit_count = 0
        for vertex in self.adjacency_list:
            if vertex.status == "not visited":
                self.depthFirstSearchVisit(vertex)


    def depthFirstSearchVisit(self, vertex):
        nonlocal visit_count
        visit_count += 1

        vertex.distance = visit_count
        vertex.status = "waiting"

        for edge in vertex.edges:
            if edge.status == "not visited":
                edge.previous = vertex
                self.depthFirstSearchVisit(edge)

        vertex.status = "visited"
        visit_count += 1
        vertex.distance_finished = visit_count

2 个答案:

答案 0 :(得分:0)

您可以在函数外定义一个函数属性,如parent.test = 0,并使用parent.test在子函数中访问它。

答案 1 :(得分:0)

在这种情况下,你可能想要使用一个类。他们很容易让你头脑发热。请注意传递的self变量,并查看here以快速解释类中的范围。

#!/usr/bin/env python3

class Family(object):

    def parent(self):
        self.test = 0
        self.child()

    def child(self):
        self.test += 1
        print(self.test)

if __name__ == "__main__":
    Family().parent()

所以,要翻译成你的代码:

#!/usr/bin/env python3

class Graph(object):
    def depthFirstSearch(self):
        for vertex in self.adjacency_list:
            vertex.status = "not visited"
            vertex.previous = None

        self.visit_count = 0
        for vertex in self.adjacency_list:
            if vertex.status == "not visited":
                self.depthFirstSearchVisit(vertex)

    def depthFirstSearchVisit(self, vertex):
        self.visit_count += 1

        vertex.distance = self.visit_count
        vertex.status = "waiting"

        for edge in vertex.edges:
            if edge.status == "not visited":
                edge.previous = vertex
                self.depthFirstSearchVisit(edge)

        vertex.status = "visited"
        self.visit_count += 1
        vertex.distance_finished = self.visit_count

class Edge(object):
    status = "not vistited"

class Vertex(object):
    def __init__(self):
        self.edges = [Edge(), Edge()]

if __name__ == "__main__":
    graph = Graph()
    graph.adjacency_list = [Vertex(), Vertex()]
    graph.depthFirstSearch()

不需要任何花哨的东西。