winsearch

Code-Stücke können hier veröffentlicht werden.
Antworten
Benutzeravatar
microkernel
User
Beiträge: 271
Registriert: Mittwoch 10. Juni 2009, 17:27
Wohnort: Frankfurt
Kontaktdaten:

Moin Moin ;)

ich arbeite mich zur Zeit in Sachen OpenSource und Git ein. Um das alles mal in der Praxis zu sehen (und zu verstehen) hab ich mal ein kleines Projekt auf GitHub platziert. ´´winsearch´´ ist ein kleines python modul, welches die Suche von Dateien auf Windows Systemen, mithilfe der Windows-internen Dateidatenbank erleichtern soll. Seit Windows Vista indexiert Windows quasi jede Benutzer-Datei in einer Datenbank. Neben Eigenschaften wie Dateigröße, Pfad und 'Zuletzt bearbeitet' speichert dieser Service auch Informationen wie bspw. MimeType oder Datei-Author.

Grüße,
microkernel
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Moin micokernel,
warum nennst Du »adodbapi« in »OleDb« um? Du solltest »\« auf jeden Fall in Deinem Code vermeiden. Ich sehe, daß Du Dich brav auf 7bit-ASCII beschränkt hast, die Angabe eines Encodings ist also überflüssig. »Query.__init__« verwendet Default-Parameter auf eine Art, die für den Nutzer ziemlich undurchsichtig und für den Programmierer recht umständlich sind. »Query.__repr__« erzeugt keine Repräsentation des Objekts.
Bei »Query.__build_query« arbeitest Du mit festen List-Indizes, was sehr wartungsintensiv und fehleranfällig ist. Viel klarer wäre es, zum Schluß per »' AND '.join(…)« alle Bedingungen zusammenzusetzen. Viel viel schlimmer ist jedoch, daß Du absolut nichts escapest. Nicht daß man dem Nutzer böse Dinge unterstellen will, aber er wundert sich, daß seine Anfragen in unverständlichen Fehlermeldungen enden.
In »Query.execute« nimmst Du »str(self)« statt des selbstbeschreibenden »self.query«. Das »conn.close()« wird nie erreicht.
Ist es eigentlich Absicht, daß »Query.select« die Spalten in eine beliebige Reihenfolge würfelt, so daß der Nutzer zum Schluß nicht weiß, wo welche Information steht? Zudem ist es sehr umständlich erst eine Liste zu erzeugen, um sie dann Element für Element mit etwas anderem zu ersetzen.

Code: Alles auswählen

    def select(self, *cols):
        self._select = [SYSTEMINDEX_COLS.get(col, col) for col in cols]
        return self
Die if-Abfrage in »Query.scope« ist sinnfrei. Ebenso in »Query.sortby«. Jetzt erst verstehe ich diese komplizierten »getattr«-Ausdrücke. Weil Du in Deiner __init__ Deine Attribute nicht ordentlich initialisierst, mußt Du hier … Initialisiere in __init__ alle Attribute!

Code: Alles auswählen

 def extensions(self, *exts):
        # ´´exts´´ without a dot at the beginning
        self._exts = list(set(self._exts)|set(exts))
        return self
»fpattern« hieß als init-Argument noch »filepattern«. Wenn ich das richtig sehe, hat der Nutzer keine Möglichkeit nach Dateien mit „_“ zu suchen.
Benutzeravatar
microkernel
User
Beiträge: 271
Registriert: Mittwoch 10. Juni 2009, 17:27
Wohnort: Frankfurt
Kontaktdaten:

Danke für die ausführliche Antwort! :)
Sirius3 hat geschrieben:Du solltest »\« auf jeden Fall in Deinem Code vermeiden.
Ja, das habe ich auch schon einmal gelesen... Allerdings ist mir keine andere Methode eingefallen den langen String über zwei Zeilen zu zerlegen. Nach Pep8 wäre der String als Ein-zeiler zu lang.
Sirius3 hat geschrieben:Ich sehe, daß Du Dich brav auf 7bit-ASCII beschränkt hast, die Angabe eines Encodings ist also überflüssig.
Oh :P Stimmt...
Sirius3 hat geschrieben:»Query.__init__« verwendet Default-Parameter auf eine Art, die für den Nutzer ziemlich undurchsichtig und für den Programmierer recht umständlich sind.
Hmm... Das habe ich mir auch schon gedacht, mir ist aber keine bessere Alternative eingefallen. Hast du irgendwelche Vorschläge?
Sirius3 hat geschrieben:»Query.__repr__« erzeugt keine Repräsentation des Objekts.
Wie meinst du das?
Sirius3 hat geschrieben:Bei »Query.__build_query« arbeitest Du mit festen List-Indizes, was sehr wartungsintensiv und fehleranfällig ist. Viel klarer wäre es, zum Schluß per »' AND '.join(…)« alle Bedingungen zusammenzusetzen. Viel viel schlimmer ist jedoch, dass Du absolut nichts escapest. Nicht daß man dem Nutzer böse Dinge unterstellen will, aber er wundert sich, daß seine Anfragen in unverständlichen Fehlermeldungen enden.
Da gebe ich dir recht. Ich werd' das ändern, sobald ich Zeit hab.
Sirius3 hat geschrieben: Ist es eigentlich Absicht, daß »Query.select« die Spalten in eine beliebige Reihenfolge würfelt, so daß der Nutzer zum Schluß nicht weiß, wo welche Information steht? Zudem ist es sehr umständlich erst eine Liste zu erzeugen, um sie dann Element für Element mit etwas anderem zu ersetzen.

Code: Alles auswählen

    def select(self, *cols):
        self._select = [SYSTEMINDEX_COLS.get(col, col) for col in cols]
        return self
Teils ja, teils nein :D Also das mit den sets habe ich nur gemacht, um redundante Doppeleinträge zu vermeiden. Dabei habe ich aber vergessen, dass bei sets die Reihenfolge der Elemente durcheinander gebracht wird :/
Sirius3 hat geschrieben:Die if-Abfrage in »Query.scope« ist sinnfrei. Ebenso in »Query.sortby«.
:oops: Da hast du recht...
Sirius3 hat geschrieben:Jetzt erst verstehe ich diese komplizierten »getattr«-Ausdrücke. Weil Du in Deiner __init__ Deine Attribute nicht ordentlich initialisierst, mußt Du hier … Initialisiere in __init__ alle Attribute!
Okay ;)
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Statt »**kw« und »kw.get(…)« was hindert Dich daran »limit=0« direkt in die Parameterliste zu schreiben?
Wenn Du von verschiedenen Objekte die __repr__-Ausgabe anschaust, findest Du zumindest immer den Namen der Klasse.
BlackJack

Ergänzend zum `__repr__()`: Die Methode gibt per Konvention entweder eine Zeichenkette zurück, die man ausführen könnte um ein äquivalentes Objekt zu bekommen, oder etwas in „Spitzen Klammern”, was a) den Namen des Datentyps enthält, und b) genug Informationen um es von anderen Objekten des selben Datentyps mit einem anderen Wert zu unterscheiden, oder allgemeiner: Informationen die man zur Fehlersuche brauchen kann. Die `object.__repr__()` produziert in CPython etwas in der Form ``'<{0} at {1}>'.format(self.__class__.__name__, hex(id(self)))``.

`__str__()` braucht man übrigens nicht überschreiben wenn man dort das gleiche Ergebnis wie bei `__repr__()` haben möchte, denn die `object.__str__()` besteht im Grunde aus ``return repr(self)``.
Antworten