Search code examples
pythonnetwork-programmingiterationping

How to iterate through a list with a Nonetype attribute? (Python)


I'm making a script for LAN host discovery in Python(without scapy yea I know, trying to use the sockets library for a learning experience). I am able to discover hosts but am having trouble separating the live hosts from the ones that returned no response because the only indicator I have is the timeout response(ping, which is either a float or None), but I cannot iterate ping as it can be a nontytpe so I tried to use hasattr to check the hosts, but I get a empty dictionary. Is there a better way I can iterate through the hosts? I can make the list of hosts a dictionary, but that doesn't solve the problem of iterating through nonetypes. Any input is appreciated, thanks.

`if __name__ == '__main__':
live = []
livee = []
for host, ping in multi_ping_query(subnet).iteritems():
    subnet = host, '=', ping
    print(subnet)
    live.append(subnet)
for ping in live:
    check = hasattr(ping, 'Nonetype')
    if check == False:
        livee.append(host)
print(livee)

Here is the function for multi_ping_query, I tried tweaking it to return a string if it does not connect however I didn't have much success with that either.

def multi_ping_query(hosts, timeout=1, step=512, ignore_errors=False):
results, host_list, id = {}, [], 0
for host in hosts:
    try:
        host_list.append(socket.gethostbyname(host))
    except socket.gaierror:
        results[host] = None
while host_list:
    sock_list = []
    for ip in host_list[:step]: # select supports only a max of 512
        id += 1
        sock_list.append(PingQuery(ip, id, timeout))
        host_list.remove(ip)
    # use timeout
    asyncore.loop(timeout)
    for sock in sock_list:
        results[sock.get_host()] = sock.get_result()
return results

Solution

  • In general, you can iterate over any iterable while excluding None values by iterating over the following generator instead:

    >>> iterable = [1, None, 2, 3, None]
    >>> iterable_nonone = (x for x in iterable if x is not None)
    >>> for x in iterable_nonone:
    ...     print(x)
    ... 
    1
    2
    3