0

我已经用 Python 编写了一些自定义类,其中有两个函数可以使用 lxml 将类加载和保存到 xml 文件中。保存功能和大部分加载功能都有效,但我在加载 xml 时遇到问题。<flows>当我在标签和元素中读取and<flow>时,在每次迭代中,以前的值都会被覆盖。例如,我有三个<step>带有元素的<flow>元素: 1 <flow>the first <step>, 2 <flow>the second<step>和 3 <flow>the third <step>。值似乎已成功加载,但最终每个值都被以下内容覆盖<step>,因此我以加载 3<step>和每个相同的 3结束<flow>

这是xml:

<step>
  <stepnumber>0</stepnumber>
  <steptitle>first step</steptitle>
  <participation>None</participation>
  <tools>tools</tools>
  <rules>rules</rules>
  <actors>
    <actor>first actor</actor>
    <actor>second actor</actor>
  </actors>
  <picture>none</picture>
  <flows>
   <flow>
     <number>0</number>
     <type>Information flow</type>
     <what>bits</what>
     <direction>From the first actor to the second one</direction>
     <firstactor>second actor</firstactor>
     <secondactor>first actor</secondactor>
   </flow>
  </flows>
</step>
<step>
 <stepnumber>1</stepnumber>
 <steptitle>second step</steptitle>
 <participation>None</participation>
 <tools>tools</tools>
 <rules>rules</rules>
 <actors>
   <actor>first actor</actor>
   <actor>second actor</actor>
   <actor>third actor</actor>
 </actors>
 <picture>none</picture>
 <flows>
   <flow>
     <number>0</number>
     <type>Financial flow</type>
     <what>none</what>
     <direction>From the first actor to the second one</direction>
     <firstactor>third actor</firstactor>
     <secondactor>first actor</secondactor>
   </flow>
   <flow>
     <number>1</number>
     <type>Information flow</type>
     <what>bits</what>
     <direction>From the first actor to the second one</direction>
     <firstactor>second actor</firstactor>
     <secondactor>first actor</secondactor>
   </flow>
 </flows>
</step>
<step>
 <stepnumber>2</stepnumber>
 <steptitle>third step</steptitle>
 <participation>None</participation>
 <tools>tools</tools>
 <rules>rules</rules>
 <actors>
   <actor>first actor</actor>
   <actor>second actor</actor>
 </actors>
 <picture>none</picture>
 <flows>
   <flow>
     <number>0</number>
     <type>Financial flow</type>
     <what>none</what>
     <direction>Both directions</direction>
     <firstactor>first actor</firstactor>
     <secondactor>second actor</secondactor>
   </flow>
   <flow>
     <number>1</number>
     <type>Information flow</type>
     <what>bits</what>
     <direction>From the first actor to the second one</direction>
     <firstactor>first actor</firstactor>
     <secondactor>second actor</secondactor>
   </flow>
   <flow>
     <number>2</number>
     <type>Information flow</type>
     <what>bits</what>
     <direction>Both directions</direction>
     <firstactor>first actor</firstactor>
     <secondactor>second actor</secondactor>
   </flow>
 </flows>

这是python代码:

    steplist = doc.xpath("//project/step")
    for k,m in enumerate(steplist):
        stepelements = m.getchildren()
        for l in stepelements:
            if l.tag == "stepnumber":
                self.steps[k] = step()
                self.steps[k].stepnumber = l.text
            elif l.tag == "steptitle":
                self.steps[k].title = l.text
            elif l.tag == "participation":
                self.steps[k].participation = l.text
            elif l.tag == "tools":
                self.steps[k].tools = l.text
            elif l.tag == "rules":
                self.steps[k].rules = l.text
            elif l.tag == "actors":
                self.steps[k].actors = []
                for j,i in enumerate(l.getchildren()):
                    self.steps[k].actors.append(l.getchildren()[j].text)
            elif l.tag == "picture":
                self.steps[k].picture = l.text
            elif l.tag == "flows":
                for s,r in enumerate(l.getchildren()):
                    self.steps[k].flows[s] = flow()
                    self.steps[k].flows[s].number = r.getchildren()[0].text
                    self.steps[k].flows[s].type = r.getchildren()[1].text
                    self.steps[k].flows[s].what = r.getchildren()[2].text
                    self.steps[k].flows[s].direction = r.getchildren()[3].text
                    self.steps[k].flows[s].actor1 = r.getchildren()[4].text
                    self.steps[k].flows[s].actor2 = r.getchildren()[5].text

结果(最后三个流程也为前面的流程重复)是:

Flow0 {0: <__main__.flow instance at 0x1005008c0>, 1: <__main__.flow instance at 0x100500830>, 2: <__main__.flow instance at 0x100500680>}
Flow1 {0: <__main__.flow instance at 0x1005008c0>, 1: <__main__.flow instance at 0x100500830>, 2: <__main__.flow instance at 0x100500680>}
Flow2 {0: <__main__.flow instance at 0x1005008c0>, 1: <__main__.flow instance at 0x100500830>, 2: <__main__.flow instance at 0x100500680>}

我怎样才能解决这个问题?完整文件可在此处获得: https ://github.com/OpenP2PDesignOrg/OpenMetaDesignApp/blob/load/classes.py https://github.com/OpenP2PDesignOrg/OpenMetaDesignApp/blob/load/test2.meta

4

1 回答 1

1

您的声明step.__init__搞砸了,因为 flow 参数的默认参数为 flow 成员的所有值分配了相同的 dict 实例和相同的 flow 实例。这是在加载定义时评估的,而不是在每次执行函数时评估的。

当您想要传递的内容是可变/通过引用时,在 Python 中执行默认参数的更常用方法是将默认值设为 None,然后在函数中包含一些逻辑,您可以在其中执行任何操作

if flows is None:
    self.flows = {0: flows()}
else:
    self.flows = flows

或者

self.flows = flows if flows is not None else {0: flows()}

或类似的规定。

于 2013-04-02T22:31:29.857 回答