Python, suds, 错误
我在尝试从远程网络服务获取方法时遇到了错误。
我的代码是:
portion=10
start=0
print self.stamp.datetime
client=self.client
while 1:
print 'getting ids...........'
fresh_ids=client.service.GetTopicsIDsUpdatedAfterDateTime(self.stamp.datetime,start,portion) #this line makes exception
if len(fresh_ids) is not 0:
for id in fresh_ids:
yield id
start=+portion
else:
print 'No updated topics anymore'
sys.exit()
这里是错误追踪信息:
/usr/lib/python2.5/site-packages/suds-0.3.5-py2.5.egg/suds/client.py
in invoke(self, args, kwargs)
469 binding = self.method.binding.input
470 binding.options = self.options
--> 471 msg = binding.get_message(self.method, args, kwargs)
472 timer.stop()
473 metrics.log.debug(
/usr/lib/python2.5/site-packages/suds-0.3.5-py2.5.egg/suds/bindings/binding.py
in get_message(self, method, args, kwargs)
96 content = self.headercontent(method)
97 header = self.header(content)
---> 98 content = self.bodycontent(method, args, kwargs)
99 body = self.body(content)
100 env = self.envelope(header, body)
/usr/lib/python2.5/site-packages/suds-0.3.5-py2.5.egg/suds/bindings/rpc.py
in bodycontent(self, method, args, kwargs)
61 p = self.mkparam(method, pd, value)
62 if p is not None:
---> 63 root.append(p)
64 n += 1
65 return root
/usr/lib/python2.5/site-packages/suds-0.3.5-py2.5.egg/suds/sax/element.py
in append(self, objects)
329 child.parent = self
330 continue
--> 331 raise Exception('append %s not-valid' %
child.__class__.__name__)
332 return self
333
<type 'exceptions.Exception'>: append list not-valid
在 suds
模块中有一个方法会引发异常:
def insert(self, objects, index=0):
"""
Insert an L{Element} content at the specified index.
@param objects: A (single|collection) of attribute(s) or element(s)
to be added as children.
@type objects: (L{Element}|L{Attribute})
@param index: The position in the list of children to insert.
@type index: int
@return: self
@rtype: L{Element}
"""
objects = (objects,)
for child in objects:
if isinstance(child, Element):
self.children.insert(index, child)
child.parent = self
else:
raise Exception('append %s not-valid' % child.__class__.__name__)
return self
在控制台里一切正常。 我卡住了。
好吧,我尝试做了一个实验:
def YieldID(self):
portion=10
start=0
print self.stamp.datetime
fresh_ids=self.client.service.GetTopicsIDsUpdatedAfterDateTime(self.stamp.datetime,start,portion) #This work
while 1:
print 'getting ids...........'
fresh_ids=self.client.service.GetTopicsIDsUpdatedAfterDateTime(self.stamp.datetime,start,portion) # This raise exception
if len(fresh_ids)!=0:
for id in fresh_ids:
yield id
start=+portion
else:
print 'No updated topics anymore'
sys.exit()
我在循环结束前调用了同样的方法,它可以正常工作。但是当进入循环内部时就出现了异常。
为什么在循环外可以工作,而在循环内就不行呢? 这就是我想问的主要问题。到底发生了什么变化?
我甚至尝试把 while
改成 for
。
1 个回答
编辑:再看了一遍代码,我注意到这一行:
start=+portion
需要改成
start += portion
这可能会让后面的分析变得不必要……但我觉得你的suds源代码里可能还是有问题,下面会解释。
我首先想问的是:你确定在调用YieldID
的时候,self.client
对象里面没有任何变化吗?
我还有一个担心——这可能并不意味着什么——就是你可能贴错了引发异常的函数的源代码。追踪信息显示异常是在调用append
时产生的,但你提供的代码是insert
的。看起来insert
的异常信息因为复制粘贴错误而把它标记成了“append”。
还有更多。如果我找到了< a href="https://fedorahosted.org/suds/browser/trunk/suds/sax/element.py?rev=462" rel="nofollow noreferrer">正确的源代码位置,那么这是append
的完整源代码,从第313行开始:
def append(self, objects):
"""
Append the specified child based on whether it is an
element or an attrbuite.
@param objects: A (single|collection) of attribute(s) or element(s)
to be added as children.
@type objects: (L{Element}|L{Attribute})
@return: self
@rtype: L{Element}
"""
if not isinstance(objects, (list, tuple)):
objects = (objects,)
for child in objects:
if isinstance(child, Element):
self.children.append(child)
child.parent = self
continue
if isinstance(child, Attribute):
self.attributes.append(child)
child.parent = self
continue
raise Exception('append %s not-valid' % child.__class__.__name__)
return self
在这里,异常是在334行抛出的,而不是你追踪信息中显示的331行。
你确定你使用的是原版的suds 0.3.5,而不是修改过的版本吗?因为原版的append
和insert
有一个有趣的区别:insert
总是把输入参数转换成一个元组,这看起来有点多余:
def insert(self, objects, index=0): // line 337
# ... snip to line 348
objects = (objects,)
而原版的append
是有条件地这样做的(见上文):
if not isinstance(objects, (list, tuple)):
objects = (objects,)
现在看看异常中的信息:
: append list not-valid
这意味着它试图添加的子项本身就是一个列表。但这怎么可能呢?如果传入的是一个列表,那么我们应该是遍历那个列表的子项……而这些子项本身不应该是列表。
嗯。也许是一个双重嵌套的列表被作为对象参数传入了append
,这似乎表明数据结构出现了严重的损坏。(见我第一个问题。)
或者……
接下来是纯粹的猜测,可能完全不对……除非它是……
或者,也许你在使用一个修改过的Suds版本,其中那个条件转换成列表的功能被去掉了,同时也没有遍历列表的过程?这可以解释你贴的代码和我在网上找到的源代码之间的3行差异(331和334)。你能再检查一下你使用的源文件,确认一下吗?