Home > Software design >  Python prevent if inside if?
Python prevent if inside if?

Time:11-02

I am new to python and wrote:

root = ET.fromstring(xml_output)
host = root.find('host')
if host:
    ports = host.find('ports')
    if ports:
        for port in ports:
            service = port.find('service')
            if service:
                print(service.attrib.get('name'))

My code works find but it looks very ugly, how can I solve this? It's going too much deep that it's hard to read, plus what If I want to add other fields under name? that will be terrible code design.

CodePudding user response:

I think the important part for you is the last print statement. If this is the case, then you could put the things in a try, except block. Depending on what you want to know about where it failed you have to make this code a bit more detailed.

root = ET.fromstring(xml_output)
try:
    host = root.find('host')  
    ports = host.find('ports')
    for port in ports:
        service = port.find('service')
        print(service.attrib.get('name'))
catch:
    print("Something did not connect")

CodePudding user response:

one alternative to nested ifs is using guard clauses:

root = ET.fromstring(xml_output)
host = root.find('host')
if not host:
    return
ports = host.find('ports')
if not ports:
    return
for port in ports:
    service = port.find('service')
    if not service:
        continue
    print(service.attrib.get('name'))

Also, in your case if ports are empty or None it will NOT loop through ports, so insted of:

if ports:
    for port in ports:
        service = port.find('service')
        if service:
            print(service.attrib.get('name'))

just:

for port in ports:
    service = port.find('service')
    if service:
       print(service.attrib.get('name'))

would suffice.

CodePudding user response:

Since what you're really doing is to print the name attribute of all service nodes under a ports node under a host node, you can find the said nodes with one call to the iterfind method with a proper XPath expression instead:

for service in ET.fromstring(xml_output).iterfind('.//host//ports//service'):
    print(service.attrib.get('name'))
  • Related