splitter - Zerlegen von Sequenzen in gleiche Portionen

Code-Stücke können hier veröffentlicht werden.
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Hi,

entschuldigt meine lange Abwesenheit. :)

Ich wollte mal eine Lösung für ein sich immer wieder stellendes Problem vorschlagen: wie zerlege ich eine Sequenz (Liste, Tupel, String) in mundgerechte Häppchen, z.B. für den Datentransfer, Paar-/Tripel-/n-Tupelbildung?

Dazu verwende ich einen Generator zur Ressourcenschonung. Die Originalsequenz wird nicht zerstückelt, bleibt also erhalten. Der Code ist kompakt und, aus meiner Sicht, recht elegant.

Code: Alles auswählen

#######################################
##  Generatorfunktion
def splitter(s, length=3):
    i = 0
    while i<len(s):
        yield s[i:i+length]
        i += length
#######################################


##	zum Test
for chunk in splitter("Hallo Welt!"):
    print chunk
	
# Hal
# lo 
# Wel
# t!

## Test anderer Laenge
for chunk in splitter("Hallo Welt!", length=5):
    print chunk
	
#Hallo
# Welt
#!
Ich hoffe, das wird mal jemandem helfen.

VG,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Benutzeravatar
snafu
User
Beiträge: 6833
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Michael Schneider hat geschrieben:wie zerlege ich eine Sequenz (Liste, Tupel, String) in mundgerechte Häppchen, z.B. für den Datentransfer, Paar-/Tripel-/n-Tupelbildung?
Ich verstehe nicht ganz, warum du eine Sequenz weiter zerlegen willst. Meinst du vielleicht einen String? Auch bezweifle ich, dass ein Standardwert von 3 soviel Sinn macht. Anstatt sich irgend einen Beispielwert zu suchen, würde ich einfach garkeinen Standardwert einsetzen.

Und zum Auslesen von Streams kann man auch einfach die gewünschte Anzahl der Bytes in der read()-Methode mitgeben. ;)
Michael Schneider hat geschrieben:Die Originalsequenz wird nicht zerstückelt, bleibt also erhalten.
Das würde mich auch in Python sehr wundern.
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Hi snafu!
snafu hat geschrieben:
Michael Schneider hat geschrieben:wie zerlege ich eine Sequenz (Liste, Tupel, String) in mundgerechte Häppchen, z.B. für den Datentransfer, Paar-/Tripel-/n-Tupelbildung?
Ich verstehe nicht ganz, warum du eine Sequenz weiter zerlegen willst. Meinst du vielleicht einen String?
Ja, auch Strings (siehe Klammer). Strings kann man zerlegen wollen, um selbst Chunks für eine low-level Streamimplementation oder zeichengenaue Zeilenumbrüche zu erzeugen.
Sequenzierte 3D-Koordinaten können bequem in eine Liste von Einzelkoordinaten umgewandelt werden:
>>> l = (1, 5, 3, 2, 7, 4)
>>> print list(splitter(l))
[(1, 5, 3), (2, 7, 4)]
Gleiches gilt für Schlüssel-Wert Paare, die dann per dict(liste) in ein Dict umgewandelt werden können. Das nur aus dem Stehgreif.
snafu hat geschrieben:Auch bezweifle ich, dass ein Standardwert von 3 soviel Sinn macht. Anstatt sich irgend einen Beispielwert zu suchen, würde ich einfach garkeinen Standardwert einsetzen.
Ok, die 3 habe ich aus meinem Fall übernommen. Aber es ist auch nur ein Codesnippet und der Standardwert kann beliebig verändert oder auch entfernt werden. Wenn in der eigenen Anwendung ein bestimmter Wert häufiger vorkommt, halte ich den Vorgabewert aber prinzipiell für sinnvoll!
snafu hat geschrieben:Und zum Auslesen von Streams kann man auch einfach die gewünschte Anzahl der Bytes in der read()-Methode mitgeben. ;)
Vom Auslesen sprach ich aber nicht. :-)
snafu hat geschrieben:
Michael Schneider hat geschrieben:Die Originalsequenz wird nicht zerstückelt, bleibt also erhalten.
Das würde mich auch in Python sehr wundern.
Das hat nichts mit der Programmiersprache zutun. Es gibt Implementierungen, die z.B. mit pop() arbeiten, um absichtlich die Ausgangssequenz zu verkürzen, was Speicher spart und in manchen Fällen den Code vereinfacht.

Gruß,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Ich vermisse irgendwie die Unterstützung für Generatoren, bzw. allgemein Iterables.
Das Leben ist wie ein Tennisball.
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Hallo,
EyDu hat geschrieben:Ich vermisse irgendwie die Unterstützung für Generatoren, bzw. allgemein Iterables.
Du spielst bestimmt auf etwas spezielles an, das Dir fehlt? Meinst Du in meinem vorgestellten Code-Snippet? Hmm, da ist was dran, auch wenn das nicht der eigentlichen Intention entspricht.

Im Modul itertools gibt es zahlreiche Funktionen und Klassen, die den Umgang und die Erzeugung von Iterationen vereinfacht. Schade nur, dass es das erst ab 2.3 gibt und ich immernoch mit 2.2 arbeiten muss...
Ja, generatoren gibt es standardmäßig auch nicht, die muss ich über __future__ importieren.

Gruß,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Moment mal .. wo rennen die Irren rum, die eine ueber 6 Jahre alte Python-Implementierung einsetzen? Selbst Debian und Jython sind schon bei 2.5 :roll:

Aber sag mal, ist das ASCII Art auch im Production Code oder hast du das fuer uns "fein" gemacht? Ich finde das unheimlich stoerend und ablenkend.
Das Keyword-Argument in Zeile 21 duerfte auch ueberfluessig sein.

@EyDu: Dann kann man aber keinesfalls mehr garantieren, dass die zugrundeliegenden Daten bestehen bleiben, ausserdem wuerde ich Generatoren anders nutzen und nicht die Lazyness gegen Broeckchen tauschen.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Ich würde auch nicht erwarten, dass die Daten bestehen bleiben, wenn ich einen Generator übergebe. Wenn ich das will, kann ich die tee-Funktion benutzen. Mich wundert es lediglich, dass die Funktionalität künstlich beschränkt wird. Über den Sinn und Unsinn einer solchen Funktion für Generatoren lässt sich natürlich wunderbar streiten.
Das Leben ist wie ein Tennisball.
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

EyDu hat geschrieben:Mich wundert es lediglich, dass die Funktionalität künstlich beschränkt wird. Über den Sinn und Unsinn einer solchen Funktion für Generatoren lässt sich natürlich wunderbar streiten.
Aha. Und welche Funktionalität wird "künstlich beschränkt"? Das Slicing funktioniert nicht bei Generatoren und Iteratoren. Eine Fallunterscheidung wäre möglich, würde den Code aber unnötig aufblähen und damit das Ziel einer kompakten Implementierung zunichte machen. Es ist laut Spezifikation nunmal ein Splitter für Sequenzen, kein Universalsplitter.

Was für eine Funktion "für" Generatoren? Das ist eine konkrete Generatorfunktion, quasi ein Generatorkonstruktur.
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

cofi hat geschrieben:Moment mal .. wo rennen die Irren rum, die eine ueber 6 Jahre alte Python-Implementierung einsetzen? Selbst Debian und Jython sind schon bei 2.5 :roll:
Da, wo Python lediglich inoffiziell und zu "Testzwecken" großzügigerweise zur Verfügung steht. Eine Migration ist äußerst problematisch, da nicht genau bekannt ist, welche Tests so existieren. Alles klar? Aber Python 2.2 ist besser als gar kein Python.
cofi hat geschrieben:Aber sag mal, ist das ASCII Art auch im Production Code oder hast du das fuer uns "fein" gemacht? Ich finde das unheimlich stoerend und ablenkend.
Ja, habe ich nur hier zur Verdeutlichung gemacht.
cofi hat geschrieben:Das Keyword-Argument in Zeile 21 duerfte auch ueberfluessig sein.
Sag mal, die PEP-8 Übersetzung hast Du aber nicht nur zur Zierde in Deiner Signatur, oder? ;-)
Ich bin schon vor einigen Jahren von diesem quick'n'dirty Mist auf sauberen, lesbaren Code umgestiegen. Spätestens mit der Einsicht, die mich immer wieder dann überkommt, wenn ich mich in meinen Code wieder reindenken musste.
Du hast recht, man muss das Schlüsselwort nicht angeben. Das hat aber zwei Vorteile:
1. weiß man, worum es sich bei diesem Parameter handelt, was besonders dann sinnvoll ist und wird, wenn weitere Parameter hinzukommen.
2. kann sich in späteren Versionen die Reihenfolge der Schlüsselwortparameter ändern. Wenn man sie beim Funktionsaufruf gleich richtig angibt, braucht man sie später nicht ändern.
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Man muss ja nich Slicing benutzen, sondern koennte einen Generator zurueckgeben, der die daten von i .. i+schritt hat, oder man erstellt eine Liste, oder oder oder ...

Naja den Link trag ich in der Signatur, um mich vor der langwierigen Referenz von PEP8 + Uebersetzung zu druecken und weil ich das urspruenglich uebersetzt habe ;)

@Schluesselwort: Ja sowas hatte ich befuerchtet, allerdings sollte man nicht still und heimlich Funktionen aendern. Wenn man den Input aendert, wird sich auch die Mechanik aendern und dann ist es IMHO besser wenn es kracht, als dass es schieflaeuft.
Haeuft sich das explizite angeben, lenkt das aber mehr ab, als dass es hilft. In der Wartung verhindert das IMHO auch, dass da jemand Hand anlegt und nur von den Angaben die falschen Schluesse zieht statt sich mit der Funktion bekannt zu machen.

Hm die Umgebung hoert sich ja abenteuerlich an. Da sollte man vielleicht Hand anlegen. Generell gilt, wenn Debian aktuellere Software einsetzt, sollte man sich Gedanken machen (Nicht zuletzt auch wegen Sicherheitsproblemen) :twisted:
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

Du meinst, ich soll einen Generator zurückgeben, der Generatoren erzeugt? :-) Also das finde ich noch eher abenteurlich, zumal ich das Ergebnis als Listen brauche, weil ich sie weiter verarbeiten möchte. Inzwischen kann man Dicts ja auch mit Generatoren füttern, aber ich muss nachher mal testen, ob das auch bei 2.2 schon ging.

Dass Du den Link nur zur schnellen Erreichbarkeit in der Signatur hast, hatte ich schon vermutet. ;-) Aber nur deshalb, weil es eben praktisch ist.

@Schlüsselwort: was hattest Du "befürchtet"?
Ich dachte Du bist ein Hacker-Typ, dann weißt Du auch, wie schnell sich der Code beim Skripten ändern kann. Und dann ist es IMHO besser, wenn es funktioniert weil man rechtzeitig die sichere Variante verwendete, als wenn es kracht.
Es ist doch einfach nur Zeitverschwendung, wenn es unnötigerweise kracht, nur weil man zu faul war, seine Schlüsselwortargumente zu benennen. Was bitte soll da schiefgehen, es läuft einfach nur sicherer.
Beispiel:

Code: Alles auswählen

>>> def auswertung(ergebnis=""):
...     print ergebnis
...
>>> auswertung("mein passwd")
mein passwd
>>> auswertung(passwd="mein passwd")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: auswertung() got an unexpected keyword argument 'passwd'
Die Auswertungsfunktion hat sich dahingehend geändert, dass nicht mehr das Ergebnis, sondern nur ein Passwort übergeben werden soll. Es knall nur bei der Schlüsselwortvariante, die stumpfen Argumente gehen durch.

Außerdem sind es nicht meine Argumente sondern die der Pythoneers und wenn ich mich nicht irre steht das auch in der Doku und vielleicht sogar im PEP 8.

Letztlich ist es jedem selbst überlassen, wie er coded. Wovon sollten sie ablenken?
Ich denke nicht, dass Schlüsselwortparameter Verwirrung stiften, ganz im Gegenteil. Häufig kennt man die Parameter, ist sich nur wegen der Reihenfolge nicht sicher. Und da fühle ich mich freier, wenn ich sie in beliebiger Reihenfolge sicher eingebe, als dass ich extra die Funktionen nachschlagen MUSS.
Aus Erfahrung weiß ich, dass (fast) jedes Quäntchen Klarheit und Übersichtlichkeit im Quellcode Gold wert ist. Und die Schlüsselwortparameter gehören für mich auf jeden Fall dazu.

Was die Umgebung angeht, kannst Du gern in meinen Annalen nachlesen, die Diskussion hatten wir schon vor Jahren. Ich arbeite bei einem internationalen Konzern und es gibt so viele unbekannte Abhängigkeiten, die mit einer höheren Version nicht mehr laufen würden, und so viele unbekannte "Testskripte", dass das sicherlich keiner Hand anlegen wird.
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Naja das war ein Gedankenexperiment, man muss Code IMO nicht so generisch schreiben, dass er fuer den konkreten Anwendungsfall schon nicht mehr benutzbar ist. Vor allem nicht bei einer einfachen Funktion.

Hm so hab ich das noch gar nicht betrachtet, allerdings ging ich nicht von sich komplett veraendernden Signaturen aus - wenn das passiert, laeuft auch etwas falsch, man kann nicht dasselbe mit ganz anderem Input machen, also muss eine andere Funktion her, am besten mit anderem Namen. Aber deine Kritik an den Positionsargumenten bleibt natuerlich gueltig.
Der sich aendernde Code, sollte sich aber nicht unbedingt in veraenderten Signaturen niederschlagen und wenn, dann nich mit dem gleichen Namen. Dein Beispiel ist insofern ungueltig, als dass nur die Ergebnis-Variante, das tut was sie soll bzw man bei dem Namen erwartet.

Wo hast du das denn in der Doku gelesen? Im Tutorial und in PEP8 steht das jedenfalls nicht und sonst faellt mir kein passender Ort ein.

Ja natuerlich ist das alles Geschmacksfrage, deshalb muessen wir das jetzt nicht so breit auswalzen ;) Ob Schluesselwortargumente Verwirrung stiften oder keinen Schaden anrichten kommt auf die Menge an. Das Problem ist, dass man das recht schnell uebertreiben kann.

Du tust mir richtig leid, dass du daran gebunden bist, aber das hoert sich nach einem Misthaufen an der unbedingt ausgemistet werden sollte, aber da habens Grosskonzerne ja nicht wirklich damit :(
lunar

@Michael Schneider: Deiner Logik nach müsstest du konsequenterweise jedes Argument als Schlüsselwort übergeben. "splitter(s='Hallo Welt!')" liest sich aber eben doch bescheuert ;) Schlüsselwortargumente stellen eigentlich eine Art optionale Argumente dar. "length" kann man schon als Schlüsselwort übergeben, weil die Signatur der Methode das eh vorsieht.

Daraus sollte man aber kein Dogma machen … wenn du meinst, "Pythoneers" (wer immer das sein soll) würden das tun, dann ist eine Quelle dafür ganz angebracht.

Zum Thema Umgebung: Wie lang soll das denn noch so gehen? Es ist doch eigentlich klar, dass sowas früher oder später schief gehen muss
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

cofi hat geschrieben:Hm so hab ich das noch gar nicht betrachtet, allerdings ging ich nicht von sich komplett veraendernden Signaturen aus - wenn das passiert, laeuft auch etwas falsch, man kann nicht dasselbe mit ganz anderem Input machen, also muss eine andere Funktion her, am besten mit anderem Namen.
Ich glaube Du würdest Dich wundern, was im praktischen quick'n'dirty Skripting so alles möglich ist und auch passiert. Recht hast Du natürlich, es war ein sehr drastisches Beispiel. In der Praxis gibt es kleine, subtile Änderungen, die anfangs und einzeln betrachet unbedeutend wirken. Aber wenn man nicht alles für einen sicheren Code getan hat (auch dann, aber nicht so stark) wird sich das Problem schnell aufbauschen.
cofi hat geschrieben:Dein Beispiel ist insofern ungueltig, als dass nur die Ergebnis-Variante, das tut was sie soll bzw man bei dem Namen erwartet.
Das habe ich jetzt nicht verstanden. Bei welchem Namen erwartest Du was? Ich meinte, dass es sein kann, dass in einer alten Version/Variante das Ergebnis an die Auswertungsfunktion übergeben wird. Später kann es aber vorkommen, dass die Daten aus einer passwortgeschützten Quelle kommen und dieser Auswertungsfunktion übergibt man dann das Passwort. Der Anwendungsfall ist nicht ganz realitätsfern, aber natürlich ein Extrem schlechter Programmierung.
cofi hat geschrieben:Wo hast du das denn in der Doku gelesen? Im Tutorial und in PEP8 steht das jedenfalls nicht und sonst faellt mir kein passender Ort ein.
Ich habe schon so viel zu Python gelesen, dass ich Dir das nicht sagen kann. Ich weiß nur, dass es um die Erläuterung der Vorteile von Schlüsselwortargumenten gegenüber Positionsargumenten ging.
cofi hat geschrieben:Ja natuerlich ist das alles Geschmacksfrage, deshalb muessen wir das jetzt nicht so breit auswalzen ;) Ob Schluesselwortargumente Verwirrung stiften oder keinen Schaden anrichten kommt auf die Menge an. Das Problem ist, dass man das recht schnell uebertreiben kann.
Deiner ersten Aussage kann ich voll und ganz zustimmen.
Die zweite kann ich allerdings immernoch nicht nachvollziehen. Ok, der Code wird länger. Aber das kommt alles der Sicherheit und Verständlichkeit des Codes zugute. Wenn man kryptischen Code schreiben will, soll man Perl verwenden. ;-)
cofi hat geschrieben:Du tust mir richtig leid, dass du daran gebunden bist, aber das hoert sich nach einem Misthaufen an der unbedingt ausgemistet werden sollte, aber da habens Grosskonzerne ja nicht wirklich damit :(
Wenn es offiziell genutzte Programmiersprache wäre und damit gepflegt werden müsste, dann sähe die Sache ganz anders aus. Da möchte ich ihnen keine Vorwürfe machen, alles kostet Geld.
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Michael Schneider hat geschrieben:Das habe ich jetzt nicht verstanden. Bei welchem Namen erwartest Du was? Ich meinte, dass es sein kann, dass in einer alten Version/Variante das Ergebnis an die Auswertungsfunktion übergeben wird. Später kann es aber vorkommen, dass die Daten aus einer passwortgeschützten Quelle kommen und dieser Auswertungsfunktion übergibt man dann das Passwort. Der Anwendungsfall ist nicht ganz realitätsfern, aber natürlich ein Extrem schlechter Programmierung.
Ich erwarte, dass eine Funktion namens ``auswertung`` sich um die Auswertung kuemmert und nicht um Auswertung und die Beschaffung der dazu noetigen Daten. Das meine ich mit ungueltig ;
Moeglich, dass das vorkommt, aber schlechte Programmierung ist das trotzdem, weshalb das nicht vorkommen sollte und kein gutes Beispiel abgibt.

Was ich in so einem Fall erwarte ist sowas:

Code: Alles auswählen

def fetch_data_from_db(db, password):
    return 42

def evaluate_data(data):
    if data == 42:
        return "Hooray!"
    else: 
        raise HolyHandgrenadeOfAntioch

def main():
    data = fetch_data_from_db("Python", "secret")
    evaluate_data(data)
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

lunar hat geschrieben:@Michael Schneider: Deiner Logik nach müsstest du konsequenterweise jedes Argument als Schlüsselwort übergeben. "splitter(s='Hallo Welt!')" liest sich aber eben doch bescheuert ;)
Ich muss Dir dahingehend recht geben, als dass es möglich und aus meiner Sicht hilfreich wäre, um die Verständlichkeit zu maximieren. Vielleicht hätte ich besser seq statt s schreiben sollen. Nichtsdestotrotz sind Positionsargumente im Gegensatz zu Argumenten mit Vorgabewert nicht vertauschbar (außer wenn mit Schlüsselwortparametern angesprochen) und können daher nicht gleichgesetzt werden.
lunar hat geschrieben:Schlüsselwortargumente stellen eigentlich eine Art optionale Argumente dar. "length" kann man schon als Schlüsselwort übergeben, weil die Signatur der Methode das eh vorsieht.
Deshalb würde ich sie auch nicht gleichsetzen. Eben weil die Schlüsselwortparameter beim Funktionsaufruf vertauscht oder weggelassen werden können.
lunar hat geschrieben:Daraus sollte man aber kein Dogma machen … wenn du meinst, "Pythoneers" (wer immer das sein soll) würden das tun, dann ist eine Quelle dafür ganz angebracht.
Pythoneers habe ich als die Leute verstanden, die von Python überzeugt sind und dessen Interessen offen vertreten - so wie es Pendants für Java und Perl gibt.
Wie oben beschrieben habe ich das zum Thema "Vorteile von Schlüsselwortparametern" gelesen. Wo genau kann ich jetzt nicht sagen, aber wenn ich wieder darauf stoße, werde ich es ergänzen.

Als Dogma würde ich das nun nicht bezeichnen. Ich würde eher sagen, dass man daraus keine allgemeine Pflicht machen darf. Man braucht nicht überall Schlüsselwortparameter verwenden, muss sich aber darüber im Klaren sein, dass der Quellcode definitiv an Klarheit verliert. Wenn nicht für einen selbst, dann für andere.

Wenn man sich aber freiwillig selbst den Grundsatz legt, zumindest nicht-Standardfunktionen mit Schlüsselwortparametern (soweit bekannt) aufzurufen, dann sehe ich darin zumindest keinen Nachteil. Welcher soll das sein? Gerade im Interesse guter Lesbarkeit und schneller, sicherer Einarbeitung in fremden Quellcode stehe ich voll dahinter.
lunar hat geschrieben:Zum Thema Umgebung: Wie lang soll das denn noch so gehen? Es ist doch eigentlich klar, dass sowas früher oder später schief gehen muss
Bitte was soll da schiefgehen? Im Gegenteil, das ist die einzige Möglichkeit um zu garantieren, dass existierende Skripte weiterhin ausgeführt werden können.

Gruß,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Michael Schneider hat geschrieben:Als Dogma würde ich das nun nicht bezeichnen. Ich würde eher sagen, dass man daraus keine allgemeine Pflicht machen darf. Man braucht nicht überall Schlüsselwortparameter verwenden, muss sich aber darüber im Klaren sein, dass der Quellcode definitiv an Klarheit verliert. Wenn nicht für einen selbst, dann für andere.
Wenn du dann feststellst, dass einige Funktionen in der Stdlib als Parameter ``a`` und ``b`` haben und sich nichtmal mittels Schlüsselwörtern aufrufen lassen, ändert das deine Meinung?

Ich glaube auch lunars Punkt ist dass der Coce eben nicht automatisch lesbarer wird, auch wenn du aus ``s`` ``seq`` macht ist es trotzdem unnötig viel Noise, speziell bei Funktionen bei denen man eine bestimmte Parameterreihenfolge sowieso erwarten würde.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Eigentlich sollte alles so gut benannt sein, daß man nicht unbedingt Keywordargumente braucht. In den seltesten Fällen übergibt man einen Wert direkt, sondern nutzt den Namen für ihn bzw nutzt eine Funktion / Klasse, die den entsprechenden Wert zurückgibt und das selbst am Namen deutlich macht, wie von cofi dargestellt. Wenn man einen Wert direkt übergibt sollte entweder kommentiert werden, was da passiert, oder es ist sowieso irgendwas triviales (oder etwas, was man hätte benennen können). An der Bennung erkennt man auch oft den Sinn. fetch_data_from_db() sollte eben nur genau das machen, und kein Password erwarten. Das liegt außerhalb der Verantwortung der Funktion. Funktionssignaturen ändern sich eben nicht absolut willkürlich. Oder sollten es in gutem Code nicht. Wenn etwas drin ist, was man nicht vermutet, gesetzt man hat genug Ahnung von der entsprechenden Funktionalität, gehört in der Regel auch nicht rein.

Dann kommt hinzu, wie von Leonidas angesprochen, das man eine bestimmte Reihenfolge (die man vom Namen erahnen können sollte) erwarten kann, idR nach der Wichtigkeit geordnet. Die meisten Funktionen, die ich gesehen habe, ordnen ihre Argumente nach Wichtigkeit. Bei dir kommt auch zuerst die Sequenz und dann die Länge, nicht andersrum.

Eine gute Benennung samt Unterteilung ist wohl das wichtigste, was ein Programmierer lernen muss. Und dann ist die generelle Verwendung von Keywordargumenten eher Lärm (wobei du recht hast, das es nicht schadet, hat man nicht sowieso eine extrem lange Signatur, was ein "Code smell" ist).

Übringens, iter() hat eine zweite Funktion, die dir vielleicht behilflich sein kann. Siehe help(iter).

EDIT: Naja, nicht allein von der Benennung. Auch vom Kontext in welchen die Definition stattfand (man wird ja wenigstens wissen, woher die Funktion kommt, ohne sich ihre Implementation anzuschauen, wie man sie definiert hat (Modulglobal, Helferfunktion, Funktion in einer Funktion um Unterfunktionalität zu übernehmen usw)) und dem Verwendungskontext.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Leonidas hat geschrieben:Wenn du dann feststellst, dass einige Funktionen in der Stdlib als Parameter ``a`` und ``b`` haben und sich nichtmal mittels Schlüsselwörtern aufrufen lassen, ändert das deine Meinung?
Das ist so falsch. Da die Parameter sich nicht als Keywords aufrufen lassen, haben sie gar keinen Namen. (Nur in den Docs muss halt irgendein Name stehen.)
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
lunar

Leonidas hat geschrieben:Ich glaube auch lunars Punkt ist dass der Coce eben nicht automatisch lesbarer wird, auch wenn du aus ``s`` ``seq`` macht ist es trotzdem unnötig viel Noise, speziell bei Funktionen bei denen man eine bestimmte Parameterreihenfolge sowieso erwarten würde.
Exakt, Michael hat mich da ziemlich missverstanden ;)

Die "Änderbarkeit" von Signaturen ist übrigens – das wollte ich noch hinzufügen – auch ein eher schwaches Argument. Ob Schlüsselwortargumente oder normale Argumente weniger Ärger machen, hängt schließlich vor allem davon ab, was man ändert. Außerdem sollte man als guter Programmierer sowieso nicht wild an den Funktionssignaturen rumspielen. Idealerweise ändert man öffentliche Schnittstellen nur vorsichtig und bei entsprechender Testabdeckung :)
Antworten