我对python不熟悉。我需要使用树来存储一些数据(文件路径),问题是当我生成树时,似乎所有对象在根之后引用相同的对象,尽管逐步调试显示相反的情况。这是我的(最小化)代码: 首先是节点类:
class PathElement:
Element = ""
IsStatic = True
Children = []
ChildrenCount = 0
def __init__(self, Element, IsStatic=True):
self.Element = Element
self.IsStatic = IsStatic
if not IsStatic:
self.Element = []
def AddChild(self, Child):
print(self, " ", Child)
self.Children.append(Child)
self.ChildrenCount = len(self.Children)
return Child
Children是PathElement节点的列表。构建树的代码:
def UnFoldAndCheck(self):
Path = PathElement("root")
Handler = Path
Index = 0
Count = len(self.Path)
while Index < Count:
element = self.Path[Index]
if something:
Child = None
Child = PathElement(element)
Handler.AddChild(Child)
Handler = None #Those added to debug the problem
Handler = Child
elif other_thing:
if condition:
if some_large_condition:
ChildExec = None
ChildExec = PathElement(element, False)
for i in range(0, 5):
ChildExec.Element.append(self.Path[Index + i])
Handler.AddChild(ChildExec)
Handler = None
Handler = ChildExec
Index += 4
elif another_condition:
ChildOp = None
ChildOp = PathElement(element, False)
Handler.AddChild(ChildOp)
Handler = None
Handler = ChildOp
elif some_else_condition:
if condition:
ChildExec = None
ChildExec = PathElement(element, False)
for i in range(0, 3):
ChildExec.Element.append(self.Path[Index + i])
Handler.AddChild(ChildExec)
Handler = None
Handler = ChildExec
Index += 2
elif different_condition:
ChildExec = None
ChildExec = PathElement(element, False)
for i in range(0, 3):
ChildExec.Element.append(self.Path[Index + i])
Handler.AddChild(ChildExec)
Handler = None
Handler = ChildExec
Index += 1
Index += 1
return Path
我的问题是,在我使用它之后构建树时,它将始终具有相同的结构: root - &gt;具有3个精确节点的对象 - &gt;相同的对象 - &gt;同一个对象到无穷大 而期望是: root - &gt;对象 - &gt;第一个孩子 - &gt;第二个孩子 - &gt;第三个孩子 - &gt;等等 我确定问题与python如何处理对象引用有关但我无法确切地看到问题所在。有帮助吗?
我用较小的代码(同一类PathElement)重现了这个问题:
from PathElement import PathElement
Path = PathElement("root")
Handler = Path
for i in range(1,6):
Child = PathElement("child"+str(i))
Handler.AddChild(Child)
Handler = Child
Tree = Path
while True:
print(Tree.Element)
if len(Tree.Children) > 0:
Tree = Tree.Children[0]
else:
break
此代码将进行无限循环
答案 0 :(得分:1)
我猜你来自Java或类似的语言。坚持使用Python的惯例非常重要(Jakob Sachs为您提供了Style Guide for Python Code的链接),因为这样可以更容易识别您的错误。
现在,这里有什么问题?当你写道:
Children
您没有提供实例字段的初始值。 您创建初始化类(静态)字段。因此,PathElement
是类class A():
i = []
a = A()
b = A()
a.i.append(1)
b.i.append(2)
assert a.i == b.i == [1,2]
的静态字段。这是一个例子:
while True:
print(Tree.Element)
if len(Tree.Children) > 0:
Tree = Tree.Children[0]
else:
break
当你尝试读取树的最左边部分(孩子0,孩子0的孩子0,......)时会发生什么?
Tree.Children
只需将PathElement.Children
替换为真实的内容:Children
,即类PathElement
的静态字段while True:
print(Tree.Element)
if len(PathElement.Children) > 0:
Tree = PathElement.Children[0] # Tree has always the same value.
else:
break
:
class PathElement:
def __init__(self, element):
self.__element = element
self.__children = []
def add_child(self, child):
self.__children.append(child)
def children(self):
return list(self.__children)
def element(self):
return self.__element
path = ["a", "b", "c", "d", "e", "f"]
root = PathElement("root")
handler = root
while path:
child = PathElement(path.pop(0)) # you can put some conditions here, take more elements of path, ...
handler.add_child(child)
handler = child
def dfs(node):
for c in node.children():
yield c.element()
yield from dfs(c)
print (list(dfs(root)))
# a b c d e f
现在,您可以写一个例子:
import keras
from keras.preprocessing import image
from keras.applications.resnet50 import preprocess_input
model = keras.models.Sequential()
model.add(keras.layers.Lambda(preprocess_input, name='preprocessing', input_shape=(224, 224, 3)))
file = '/path/to/an/image.jpeg'
x = np.array(image.img_to_array(image.load_img(file, target_size=(224, 224))))
preprocessed_x = preprocess_input(x)
predicted_x = model.predict(x.reshape(1,224,224,3)).reshape(224,224,3)