从sleekxmpp迁移至slixmpp时Future对象无find_all属性报错如何解决
报错原因
- 核心差异是sleekxmpp为同步框架,
resp.send()会直接阻塞等待并返回收到的IQ响应stanza对象;而slixmpp是全异步框架,resp.send()不会阻塞,直接返回一个_asyncio.Future对象,该对象本身没有XML节点处理的find_all方法,因此触发属性错误。 - 原代码没有按照异步语法等待Future执行完成拿到实际的stanza结果,就直接调用了只有stanza才有的方法。
修复方案
需要对代码做两处核心改动:
- 该段逻辑必须放在
async修饰的异步函数内 - 调用
resp.send()时添加await关键字,等待异步执行完成拿到实际的IQ响应stanza对象后再做解析
修改后的完整代码
import asyncio from slixmpp import Iq from slixmpp.exceptions import IqError, IqTimeout import xml.etree.ElementTree as ET # 注意:该方法必须是async修饰的异步方法 async def search_users(self): #Create iq Stanza resp = self.Iq() resp['type'] = 'set' resp['to'] = 'search.michaela-pc' resp['from'] = self.jid resp['id'] = 'search_result' #Service discovery stanza for getting all users resp.append(ET.fromstring("<query xmlns='jabber:iq:search'>\ <x xmlns='jabber:x:data' type='submit'>\ <field type='hidden' var='FORM_TYPE'>\ <value>jabber:iq:search</value>\ </field>\ <field var='Username'>\ <value>1</value>\ </field>\ <field var='search'>\ <value>*</value>\ </field>\ </x>\ </query>")) try: # 核心改动:添加await等待异步返回结果 results = await resp.send() # Extract info from recived stanza for i in results.find_all('.//{jabber:x:data}value'): if ((i.text != None) and ("@" in i.text)): print(i.text) except IqError as e: print("Could not get users") except IqTimeout: print("Server did not respond")
如果是在非异步上下文调用该方法,需要用asyncio的事件循环驱动执行,示例:
asyncio.run(search_users())
内容的提问来源于stack exchange,提问作者Dina
相关产品推荐
相关产品推荐

