Wie baue ich eine Funktion, wo man nicht genau weiß wieviele Parameter da rein kommen?
Weils immer unterschiedlich ist, je nach dem wo man diese einsetzt.
geht sowas?
x parametre
klar
Edit: Ups, die Erklärung vergessen.
p1 und p2 ist ein einfacher PArameter, wie du ihn sicher schon kennst
args erwartet eine Liste, also zB:
und **kwargs erwartet eine zuweisung zB.
Code: Alles auswählen
def function(p1, p2, *args, **kwargs):
print ("Parameter 1: ", p1)
print ("Parameter 2: ", p2)
print ("Liste:", args)
print ("Dictionary: ", kwargs)
p1 und p2 ist ein einfacher PArameter, wie du ihn sicher schon kennst
args erwartet eine Liste, also zB:
Code: Alles auswählen
def function(*args):
print (args)
function(1,2,3,4,5)
Code: Alles auswählen
def function(**kw):
print (kw)
function(para1=1, para2=2)
Zuletzt geändert von Xynon1 am Freitag 15. Oktober 2010, 13:35, insgesamt 1-mal geändert.
Siehe auch den entsprechenden Abschnitt im Tutorial: http://docs.python.org/tutorial/control ... -functions
https://www.xing.com/go/invite/18513630.6a91d4
@Sync32: Wobei man die */**-"Magie" nicht benutzen sollte wenn es Alternativen gibt, zum Beispiel eine Liste als Argument statt beliebig viele Argumente.
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Als gutes Anwendungsbeispiel fallen mir die div. Template-Engines und deren "render"-Funktionen ein. Da man üblicherweise nicht wissen kann, welche und wie viele Objekte an ein Template übergeben werden müssen, nutzen diese Libs diese Funktionalität.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Ganz schlechtes Beispiel, da hat man schliesslich einen Kontext den man übergibt und da wäre es besser einfach explizit ein dict zu übergeben.Hyperion hat geschrieben:Als gutes Anwendungsbeispiel fallen mir die div. Template-Engines und deren "render"-Funktionen ein. Da man üblicherweise nicht wissen kann, welche und wie viele Objekte an ein Template übergeben werden müssen, nutzen diese Libs diese Funktionalität.
Du meinst Dekoratoren die eine Funktion zurückgeben, dir die dekorierte Funktion/Klasse aufruft? Das wäre tatsächlich ein gutes Beispiel, da kommt man schliesslich nicht drum herum./me hat geschrieben:Wie wäre es denn dann mit Dekoratoren?
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Kannst Du das ein wenig näher ausführen? Im Moment sehe ich da nicht, worauf damit hinaus willst. Sowohl in bottle, jinja und mako sieht man viele Beispiele, bei denen man Keyword-Parameter an eine render()-Funktion übergibt. Ich dachte genau darüber reden wir hier u.a.DasIch hat geschrieben:Ganz schlechtes Beispiel, da hat man schliesslich einen Kontext den man übergibt und da wäre es besser einfach explizit ein dict zu übergeben.Hyperion hat geschrieben:Als gutes Anwendungsbeispiel fallen mir die div. Template-Engines und deren "render"-Funktionen ein. Da man üblicherweise nicht wissen kann, welche und wie viele Objekte an ein Template übergeben werden müssen, nutzen diese Libs diese Funktionalität.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
IMHO ist es schlechtes Design Keyword Argumente für etwas anderes zu nutzen als optionale Argumente, erst recht wenn ich sie dafür nutze um Daten zu repräsentieren. Die syntaktische und semantische Ebene der Programmiersprache sollte einfach nicht mit der Verarbeitung der Daten vermischt werden, aus dem gleichen Grund vermeidet man schliesslich auch Typprüfungen.
@DasIch: I„Syntaktische und semantische Ebene“?! Ist das jetzt nicht etwas sehr dogmatisch? Der Kontext eines Templates ist doch fast immer statisch, alle darin enthaltenen Namen sind meist zur Entwicklungszeit bekannt. Es ist doch nur pragmatisch und praxisnah, wenn die API den Kontext über Schlüsselwörter abbildet, statt auf einem separat zu erzeugenden Wörterbuch zu beharren.
Ganz abgesehen davon kann man diese Argumentation auch ganz einfach umdrehen. Der Kontext ist ja letztlich nichts anderes als der Namensraum für das Template, ein Schlüssel im Kontext also eigentlich dasselbe wie ein Name in Python. Der Kontext ist im Template auf der „syntaktischen und semantischen Ebene“, und sollte es somit auch in Python sein.
Ganz abgesehen davon kann man diese Argumentation auch ganz einfach umdrehen. Der Kontext ist ja letztlich nichts anderes als der Namensraum für das Template, ein Schlüssel im Kontext also eigentlich dasselbe wie ein Name in Python. Der Kontext ist im Template auf der „syntaktischen und semantischen Ebene“, und sollte es somit auch in Python sein.
@lunar: Also ich seh's ähnlich dogmatisch. ``ham(something, spam=42, eggs=23)`` vs. ``ham(something, dict(spam=42, eggs=23))`` erscheint mir jetzt echt nicht unzumutbar viel mehr Tipparbeit. Und man verbaut sich nicht die Möglichkeit der `ham()`-Funktion selbst später noch benannte Argumente hinzufügen zu können die auch im Dictionary vorkommen dürfen/können.
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Nun frage ich mich aber, wieso die div. Template Autoren diese Möglichkeit vorgesehen haben? Sehen die das allesamt anders, oder ist es eine Art "historische" Entwicklung? In vielen Tutorials sehe ich aber auch, dass die Autoren davon Gebrauch machen, anstatt die auch mögliche dict()-Variante zu nutzen.
@DasIch: Nutzt ihr in inyoka also die "render(name, dict())"-Variante?
Ich persönlich habe mir ehrlich gesagt nie solche Gedanken darüber gemacht; da ich dieses Konzept von den div. render()-Funktionen einfach kannte. Daher habe ich das mal "naiv" als gutes Beispiel genannt; vielleicht ist es hier also gar nicht "gut", sondern nur ein Beispiel, wo das in der Praxis verwendet wird? (und ggf. also sogar ein schlechtes)
Ich selber habe im Sommer mal eine Template Engine für Java benutzt und fand es dort extrem nervig, dass ich mir erst eine Map zusammenbasteln musste, in der ich dann die div. Parameter an mein Template übergeben konnte. In dem Zusammenhang empfand ich die Möglichkeit in Python, beliebig viele Parameter an eine Funktion zu übergeben, als angenehmer. Aber ich gebe zu ich bin auch kein Experte bei solchen Sprach theoretischen Diskussionen und lasse mich da gerne eines besseren belehren.
@DasIch: Nutzt ihr in inyoka also die "render(name, dict())"-Variante?
Ich persönlich habe mir ehrlich gesagt nie solche Gedanken darüber gemacht; da ich dieses Konzept von den div. render()-Funktionen einfach kannte. Daher habe ich das mal "naiv" als gutes Beispiel genannt; vielleicht ist es hier also gar nicht "gut", sondern nur ein Beispiel, wo das in der Praxis verwendet wird? (und ggf. also sogar ein schlechtes)
Ich selber habe im Sommer mal eine Template Engine für Java benutzt und fand es dort extrem nervig, dass ich mir erst eine Map zusammenbasteln musste, in der ich dann die div. Parameter an mein Template übergeben konnte. In dem Zusammenhang empfand ich die Möglichkeit in Python, beliebig viele Parameter an eine Funktion zu übergeben, als angenehmer. Aber ich gebe zu ich bin auch kein Experte bei solchen Sprach theoretischen Diskussionen und lasse mich da gerne eines besseren belehren.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Ok, also quasi wie in der flask-Doku erklärt. Danke für die Info!DasIch hat geschrieben:Die Views haben einen templated Dekorator und geben den Kontext als dict zurück.Hyperion hat geschrieben:@DasIch: Nutzt ihr in inyoka also die "render(name, dict())"-Variante?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
@Hyperion: Ist das hauptsächlich nervige bei Java nicht, dass es weder `Map`-Literale noch die Möglichkeit gibt ein `Map`-Exemplar wie `dict()` mit Schlüsselwort-Argumenten zu füllen? Das werden in Java dann ja erst mal richtig viele Quelltextzeilen für etwas was eigentlich ganz einfach ist, oder zumindest sein sollte.
Bei der Signatur von `dict()` kann ich mich übrigens auch an Diskussionen in der englishsprachigen Newsgroup erinnern, dass es blöd ist, dass man sich dadurch Möglichkeiten verbaut hat, wie zum Beispiel ``dict(capacity=100)`` um die Hashtabelle beim Erstellen auf eine bestimmte Grösse vorzuinitialisieren, oder in Anlehnung an das `key`-Argument bei `list.sort()`/`sorted()`/`min()` usw. eine andere Funktion anzugeben als `hash()` um den Schlüssel in die Hashtabelle einzutragen.
Bei der Signatur von `dict()` kann ich mich übrigens auch an Diskussionen in der englishsprachigen Newsgroup erinnern, dass es blöd ist, dass man sich dadurch Möglichkeiten verbaut hat, wie zum Beispiel ``dict(capacity=100)`` um die Hashtabelle beim Erstellen auf eine bestimmte Grösse vorzuinitialisieren, oder in Anlehnung an das `key`-Argument bei `list.sort()`/`sorted()`/`min()` usw. eine andere Funktion anzugeben als `hash()` um den Schlüssel in die Hashtabelle einzutragen.
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Stimmt! Ginge das, wäre es auch in Java in solchen Fällen erträglich(er). Ok, dank Eclipse und Co. tippern sich solche Snippets auch relativ fix, dennoch ist es ziemliche viel Boilerplate.BlackJack hat geschrieben:@Hyperion: Ist das hauptsächlich nervige bei Java nicht, dass es weder `Map`-Literale noch die Möglichkeit gibt ein `Map`-Exemplar wie `dict()` mit Schlüsselwort-Argumenten zu füllen?
Stimmt. An solche Dinge denkt man irgend wie selten - bis es einen "trifft". Andererseits fällt mir nicht ein, wie man das sonst lösen könnte / sollte? Manchmal ist der hauptsächliche use-case imho wichtiger, als alle Eventualitäten abzudecken.Bei der Signatur von `dict()` kann ich mich übrigens auch an Diskussionen in der englishsprachigen Newsgroup erinnern, dass es blöd ist, dass man sich dadurch Möglichkeiten verbaut hat, wie zum Beispiel ``dict(capacity=100)`` um die Hashtabelle beim Erstellen auf eine bestimmte Grösse vorzuinitialisieren, oder in Anlehnung an das `key`-Argument bei `list.sort()`/`sorted()`/`min()` usw. eine andere Funktion anzugeben als `hash()` um den Schlüssel in die Hashtabelle einzutragen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
@BlackJack: Es ist Dir bestimmt nicht entgangen, dass auch die von Dir gezeigte Alternative, die in der Tat nicht wesentlich mehr Tipparbeit darstellt, nur deswegen funktioniert, weil auch die Signatur von "dict()" dank **-Magie beliebig viele Schlüsselwortargumente akzeptiert. Ich bedauere, Dir zu widersprechen, doch es fällt mir angesichts dieses Umstandes schwer, Dein Dogma zu verstehen.
Ich will bestimmt nicht abstreiten, dass die Asterik-Formen in der Signatur der Lesbarkeit des Quelltexts durchaus abträglich sein können, und den Gebrauch anderer Namen in der Signatur erschweren oder gar verhindern, doch in Fällen, in denen diese Formen der Lesbarkeit zuträglich sind, ist ihrer Anwendung meines Erachtens durchaus zu begrüßen. Der diskutierte Fall der ".render()"-Methoden für Template-Objekte fällt nun genau in diese Kategorie.
Im Übrigen stellt die Signatur dieser Methoden in den üblichen Template-Engines nun mittlerweile ein mehr oder weniger unveränderliches Faktum dar, so dass die Diskussion über Sinn und Unsinn dieses speziellen Falls mir reichlich überflüssig erscheint.
Ich will bestimmt nicht abstreiten, dass die Asterik-Formen in der Signatur der Lesbarkeit des Quelltexts durchaus abträglich sein können, und den Gebrauch anderer Namen in der Signatur erschweren oder gar verhindern, doch in Fällen, in denen diese Formen der Lesbarkeit zuträglich sind, ist ihrer Anwendung meines Erachtens durchaus zu begrüßen. Der diskutierte Fall der ".render()"-Methoden für Template-Objekte fällt nun genau in diese Kategorie.
Im Übrigen stellt die Signatur dieser Methoden in den üblichen Template-Engines nun mittlerweile ein mehr oder weniger unveränderliches Faktum dar, so dass die Diskussion über Sinn und Unsinn dieses speziellen Falls mir reichlich überflüssig erscheint.
@lunar: Nein das ist mir nicht entgangen -- warum das auch bei `dict()` schlecht ist, habe ich aber auch schon geschrieben. Nur kann ich die Signatur von `dict()` nicht mehr ändern -- da ist die API nun mal vergeigt worden -- aber ich kann sehr wohl in meinem Quelltext nicht den gleichen Fehler machen.
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Mir ist in dem Zusammenhang noch ein schönes Beispiel eingefallen: die format()-Methode von Strings! Auch da ließe sich die Argumentation der dict()-Befürworter anwenden, oder irre ich hier?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert