Daniel
Daniel

Reputation: 51

Python prevent if inside if?

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.

Upvotes: 1

Views: 88

Answers (3)

blhsing
blhsing

Reputation: 107095

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'))

Upvotes: 1

ihpar
ihpar

Reputation: 676

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.

Upvotes: 1

Klaus
Klaus

Reputation: 315

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")

Upvotes: 1

Related Questions