我想包装for循环的功能,以便使用它更直观。在我的情况下,我必须解析xml文件,如下所示:
<instance id="line-n.w8_047:15696:">
<answer instance="line-n.w8_047:15696:" senseid="product" />
<context> context1 </context>
</instance>
<instance id="line-n.w8_088:12441:">
<answer instance="line-n.w8_088:12441:" senseid="product" />
<context> another context</context>
</instance>
我为Instance
写了一个类:
class Instance:
def __init__(self, id, answer, context):
self.id = id
self.answer = answer
self.context = context
我编写了下一个枚举实例的函数:
import xml.etree.ElementTree as ET
def enum_instances(file_path, action):
for instance_xml in ET.parse(file_path).getroot().find('lexelt'):
action(Instance(
instance_xml.attrib['id'],
instance_xml.find('answer').attrib['senseid'],
instance_xml.find('context').text)
)
action
参数是使用Instance
执行某些操作的回调,如下所示:
enum_instances('/path/to/xml', lambda instance: print(instance.context))
但它看起来有点奇怪,我希望它更直观,就像这样:
for instance in enum_instances(file_path):
print(instance.context)
实现'iterable'功能的最佳方法是什么? 感谢
答案 0 :(得分:3)
在这种情况下获胜的发电机。像
这样的东西def enum_instances(file_path):
for instance_xml in ET.parse(file_path).getroot().find('lexelt'):
yield Instance(
instance_xml.attrib['id'],
instance_xml.find('answer').attrib['senseid'],
instance_xml.find('context').text)
然后你可以准确地说出你的要求:
for instance in enum_instances(file_path):
print(instance.context)
答案 1 :(得分:1)
不是将callable传递给你的函数,而是让它产生Instance
,然后你可以得到你想要的行为,例如:
def enum_instances(file_path, action=None):
for instance_xml in ET.parse(file_path).getroot().find('lexelt'):
instance = Instance(
instance_xml.attrib['id'],
instance_xml.find('answer').attrib['senseid'],
instance_xml.find('context').text)
if action is not None:
instance = action(instance)
yield instance
在这种情况下 - 我已将[{1}}默认为action
,但在None
之前,您可以通过某种方式传递函数以某种方式改变instance
如果需要的话。
然后:
yield