1

在下面的代码中,我试图将字符串 '1/2/3/4/5/6/' 解析为层次结构树,期望输出应该是这样的:

# 1 -> 2 
# 2 -> 3
# 3 -> 4
# 4 -> 5
# 5 -> 6

但它返回:

# 1 -> [2, 3, 4, 5, 6]

打印了一些变量后,我找到了原因,变量'a1'不仅代表第一个'a1',还代表所有名为'a1'的变量,每次调用方法,它都会产生一个'a1'变量,并操作它。Python 不喜欢其他 OO 语言,'a1' 预计是当前调用中唯一的变量。所以我的问题是,在 Python 中解决这类问题的最佳方法是什么?

class A(object):
    name = ''
    children = []

    def __repr__(self):
        return '%s -> %s' % (self.name, self.children)

def recurse(a1, s):
    if len(s) == 0: return

    s1 = s[0:s.find('/')]
    a1.name = s1
    print 's1: %s' % (s1)

    s2 = s[s.find('/') + 1:]
    print 's2: %s' % (s2)

    a2 = A()
    a1.children.append(a2) # Problem: why all child append into variable 'a' and all children too?
    # print 'locals() -> ', locals()    when I print locals(), I got the reason, but what's the best way to fix the problem?
    recurse(a2, s2)

a = A()
recurse(a, '1/2/3/4/5/6/') # input string required to ends with '/'

# expect: 
# 1 -> 2 
# 2 -> 3
# 3 -> 4
# 4 -> 5
# 5 -> 6

print a
4

2 回答 2

4

你的孩子是一个类属性,所以所有的实例都将共享和修改同一个列表

class A(object): 
    name = ''                      # these are class
    children = []                  # attributes

你应该给每个实例它自己的列表

class A(object):
    def __init__(self):
        self.name = ''             # these are instance
        self.children = []         # attributes
于 2013-06-03T02:49:19.263 回答
1

由于您将每个节点作为子节点添加到前一个节点,因此您获得了链式关系。您可以使函数返回节点列表:

class A(object):
    def __init__(self,name):
        self.name = name
        self.children = []
    def __repr__(self):
        return '%s -> %s' % (self.name, self.children)

def recurse(s,l=[]):
    v = s.split("/")
    if len(v) < 3: return
    a1,a2 = A(v[0]), A(v[1])
    a1.children.append(a2)
    v.pop(0)
    l.append(a1)
    recurse("/".join(v),l)
    return l

for i in recurse('1/2/3/4/5/6/'):
    print i

输出:

1 -> [2 -> []]
2 -> [3 -> []]
3 -> [4 -> []]
4 -> [5 -> []]
5 -> [6 -> []]
于 2013-06-03T03:04:08.303 回答