Es gibt eine Menge Zeilen die länger als 80 Zeichen sind. Ich denke sehr häufig sind es lange Kommentare die ans Ende einer Zeile gesetzt wurden. Das ist je nach Umbruchverhalten der Anzeige schwer bis sehr schwer zu lesen. Und dabei sollte man nicht nur an den eigenen Editor denken, sondern auch an die Editoren anderer Leute, das Konsolenfenster, Textfelder in GUIs für Versionskontrollsoftware, E-Mail-Clients, Webseiten, und so weiter. Eben alles wo Quelltexte/Patches noch so angezeigt werden und gelesen werden müssen.
Einige von den Kommentaren sind auch überflüssig. Ein Kommentar sollte einen Mehrwert zum Code bieten. Einige bei Dir sagen nochmal das Offensichtliche was schon im Code steht. Was Code macht sollte man nur kommentieren wenn der Code zu komplex ist und man ihn nicht einfacher bekommt. Kommentare sind eher dazu da zu beschreiben warum der Code das tut was er tut.
Die `min()`/`max()`-Funktionen kann man auch mit mehreren Argumenten aufrufen. Also statt ``min([a, b])`` geht auch ``min(a, b)``. IMHO ist das Beschränken der Ports da nicht an der richtigen Stelle beziehungsweise generell nicht gut. In der `__init__()` würde ich eher auf die Grenzen prüfen und auch ob `port_start` kleiner oder gleich `port_end` ist, und falls nicht eine Ausnahme auslösen. Das wäre schliesslich eine fehlerhafte Eingabe vom Benutzer.
Den Code im ``if __name__ == '__main__':``-Zweig solltest Du noch in eine Funktion stecken. Sonst hast Du sowohl in Funktionen als auch auf Modulebene einige identische Namen definiert. So etwas kann zu subtilen Fehlern führen, wenn man dann doch aus versehen mal auf einen Namen auf Modulebene zugreift, den man in einer Methode für einen Lokalen hält.
``except`` und ``print`` sind keine Funktionen. ``print`` ist das erst in Python 3, da Du aber `random.shuffle()` auf das Ergebnis von `range()` anwendest, muss das Python 2-Quelltext sein:
Code: Alles auswählen
>>> import random
>>> random.shuffle(range(42))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.1/random.py", line 270, in shuffle
x[i], x[j] = x[j], x[i]
TypeError: 'range' object does not support item assignment
Beide Portscanner sind überflüssigerweise Klassen. Du nutzt nirgends den Umstand dass das eine Klasse ist auch tatsächlich aus. Klassen sind kein Selbstszweck und in Python auch nicht das Mittel um einen Namensraum für einfache Funktionen zu schaffen. Dafür gibt es Module.
Statt einer `Semaphore` hätte man auch ein `Lock` nehmen können. Und die kann man mit der ``with``-Anweisung kombinieren. Das ist sicherer.
Beide Scanner enthalten ähnlichen Quelltext, den man heraus ziehen könnte.
Es gibt in Python keine ``private``-Methoden. Auf Modulebene schon gar nicht. Implementierungsdetails werden mit *einem* führenden Unterstrich gekennzeichnet.
Die Argumente könnte man mit `argparse` verarbeiten.