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
winsearch
- microkernel
- User
- Beiträge: 271
- Registriert: Mittwoch 10. Juni 2009, 17:27
- Wohnort: Frankfurt
- Kontaktdaten:
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.
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!
»fpattern« hieß als init-Argument noch »filepattern«. Wenn ich das richtig sehe, hat der Nutzer keine Möglichkeit nach Dateien mit „_“ zu suchen.
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
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
- microkernel
- User
- Beiträge: 271
- Registriert: Mittwoch 10. Juni 2009, 17:27
- Wohnort: Frankfurt
- Kontaktdaten:
Danke für die ausführliche Antwort!
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:Du solltest »\« auf jeden Fall in Deinem Code vermeiden.
Oh Stimmt...Sirius3 hat geschrieben:Ich sehe, daß Du Dich brav auf 7bit-ASCII beschränkt hast, die Angabe eines Encodings ist also überflüssig.
Hmm... Das habe ich mir auch schon gedacht, mir ist aber keine bessere Alternative eingefallen. Hast du irgendwelche Vorschläge?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.
Wie meinst du das?Sirius3 hat geschrieben:»Query.__repr__« erzeugt keine Repräsentation des Objekts.
Da gebe ich dir recht. Ich werd' das ändern, sobald ich Zeit hab.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.
Teils ja, teils nein 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: 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
Da hast du recht...Sirius3 hat geschrieben:Die if-Abfrage in »Query.scope« ist sinnfrei. Ebenso in »Query.sortby«.
OkaySirius3 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!
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.
Wenn Du von verschiedenen Objekte die __repr__-Ausgabe anschaust, findest Du zumindest immer den Namen der Klasse.
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)``.
`__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)``.