def f(x[i]):
Warum willst Du als Parameter einen Listeneintrag?
Also was soll Deiner Meinung nach diese Syntax bewirken? Kannst Du ein vollständiges Pseudo-Beispiel geben, in der diese Syntax sinnvoll verwendet wird?
Also was soll Deiner Meinung nach diese Syntax bewirken? Kannst Du ein vollständiges Pseudo-Beispiel geben, in der diese Syntax sinnvoll verwendet wird?
Code: Alles auswählen
def function(some_list, index):
print(some_list[index])
Du kannst einen Listeneintrag als Parameterwert übergeben, aber der Name des Parameters selber muss eben das sein: ein Name.
Ich schließe mich da Sirius an: Was erwartest du, was da passieren soll?
Naja, man könnte erwarten, dass Parameter so wie alle anderen Zuweisungen funktionieren:
Warum sollte bei
nicht auch `xs` verändert werden? Von der Sinnhaftigkeit sehe ich das ungefähr auf einer Ebene mit `xs[0]` als Iterationsvariable in einer `for`-Schleife.
Code: Alles auswählen
In [1]: xs = [0, 1, 2]
In [2]: xs[0] = 42
In [3]: xs
Out[3]: [42, 1, 2]
In [4]: for xs[0] in range(10):
...: print(xs)
...:
[0, 1, 2]
[1, 1, 2]
[2, 1, 2]
[3, 1, 2]
[4, 1, 2]
[5, 1, 2]
[6, 1, 2]
[7, 1, 2]
[8, 1, 2]
[9, 1, 2]
In [5]: xs
Out[5]: [9, 1, 2]
In [6]: (xs[0], xs[1]) = 27, 42
In [7]: xs
Out[7]: [27, 42, 2]
Code: Alles auswählen
def f(xs[0]):
pass
f(42)
Krass, mir war bisher gar nicht klar, dass ``for xs[0] in range(10): print(xs)`` überhaupt funktioniert. Wollte auch etwas entsprechendes schreiben. Habe es vorher jedoch ausprobiert und gesehen, dass das gezeigte Ergebnis tatsächlich zutrifft.
Zur Frage: Der Name für ein Argument der Funktion ist ja bloß ein Stellvertreter für den übergebenen Wert. Also etwa: "Übergebe Wert 1 als x". Das ist ein anderes Konzept als wenn der Wert magisch zur Laufzeit ermittelt wird. Was übergibt man in dem Fall? Die komplette Liste `xs` und er zieht sich den Wert an Index 0?
- __blackjack__
- User
- Beiträge: 13131
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@narpfel: Naja, es ist noch ein bisschen sinnloser als eine Zuweisung an ``x[0]`` im Kopf einer ``for``-Schleife: `xs` müsste ja eigentlich eine Konstante sein, denn sonst würde die Funktion hier ja auf einem globalen Wert arbeiten. Wenn es eine Konstante ist, dann sollte man der aber keine anderen Werte/Elemente zuweisen. Also gäbe es für so ein Konstrukt noch weniger Anwendungsfälle.
Wie spielt das mit expliziten Schlüsselwortargumenten zusammen? Was ist mit Default-Werten? Was ist mit ``*``- und ``**``-Magie beim Aufruf der Funktion, wie funktioniert das? ``f(xs[0]=42)`` kann man sich ja noch vorstellen. Aber geht dann auch ``f(xs[1]=42)``? Wie müsste `d` in ``f(**d)`` aussehen wenn man so eine Funktion aufrufen möchte? Wie müssen die entsprechenden Aufrufe bzw. Ergebnisse aus dem `inspect`-Modul dann aussehen? Heissen die Argumentnamen dann nicht mehr Argumentnamen sondern Argumentausdrücke? Und werden die dann statt als Zeichenketten mit dem Namen, als AST-Nodes zurückgegeben? Wie komplex wird Code der jetzt mit Zeichenketten mit Namen arbeitet dadurch, also was bezahlt man da am Ende über zusätzliche Komplexität, für welchen Gewinn?
Wie spielt das mit expliziten Schlüsselwortargumenten zusammen? Was ist mit Default-Werten? Was ist mit ``*``- und ``**``-Magie beim Aufruf der Funktion, wie funktioniert das? ``f(xs[0]=42)`` kann man sich ja noch vorstellen. Aber geht dann auch ``f(xs[1]=42)``? Wie müsste `d` in ``f(**d)`` aussehen wenn man so eine Funktion aufrufen möchte? Wie müssen die entsprechenden Aufrufe bzw. Ergebnisse aus dem `inspect`-Modul dann aussehen? Heissen die Argumentnamen dann nicht mehr Argumentnamen sondern Argumentausdrücke? Und werden die dann statt als Zeichenketten mit dem Namen, als AST-Nodes zurückgegeben? Wie komplex wird Code der jetzt mit Zeichenketten mit Namen arbeitet dadurch, also was bezahlt man da am Ende über zusätzliche Komplexität, für welchen Gewinn?
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Den Schlüssel hat mir /me gegeben; der Parameter nuss ein Name sein.
Mein Ziel war, die Einträge einer Liste von Permutationen von 1,2,3,4 zeilenweise in ein 2x2-Fenster einer Matrix zu schreiben und so ein 4x4-Soduko herzustellen. Das ist gelungen, jedoch kommen dabei viermal solche Zuweisungen mit immer gleichen rechten Seiten für verschiede p und i vor:
a[0][2] = p[0]
a[0][3] = p[1]
a[1][2] = p[2]
a[1][3] = p[3]
Das wollte ich vereinfachen, indem ich eine Funktion sq(p) aufrufe, um ein 9x9-Sudoku herzustellen.
Und die Definition dieser Funktion ist misslungen.
Mein Ziel war, die Einträge einer Liste von Permutationen von 1,2,3,4 zeilenweise in ein 2x2-Fenster einer Matrix zu schreiben und so ein 4x4-Soduko herzustellen. Das ist gelungen, jedoch kommen dabei viermal solche Zuweisungen mit immer gleichen rechten Seiten für verschiede p und i vor:
a[0][2] = p[0]
a[0][3] = p[1]
a[1][2] = p[2]
a[1][3] = p[3]
Das wollte ich vereinfachen, indem ich eine Funktion sq(p) aufrufe, um ein 9x9-Sudoku herzustellen.
Und die Definition dieser Funktion ist misslungen.
@__blackjack__: Hm, gute Fragen. Da man ja Funktionen auch lokal definieren kann, ist „`xs` müsste global sein“ IMHO kein Argument. Genauso wie `for xs[0] in ...` auch global erlaubt ist, aber nicht benutzt werden sollte.
Man könnte erfordern, dass diese Art von Parametern positional-only ist, weil es keine richtige Syntax gibt (bzw. geben kann), um den Namen beim Aufruf anzugeben.
Für `inspect` könnte man entweder sagen, dass der Parameter keinen Namen hat (Wozu braucht ein positional-only-Parameter einen Namen? Und nicht alle Callables haben `inspect`able Signaturen, z. B. wenn sie in C geschrieben sind.) oder es könnte das, was tatsächlich im Quelltext steht, als Parametername genommen werden. Also bei `def f((xs + ys)[42 + 27]): pass` wäre der Name dann `(xs + ys)[42 + 27]`. Zeichenkette ist Zeichenkette, würde sich dadurch also wirklich Code verkomplizieren?
Und für welchen Gewinn? Keine Ahnung, aber ich fand die Frage nachvollziehbar, warum das nicht erlaubt ist, weil es eine scheinbar willkürliche Restriktion ist. (Auch wenn die Frage am Ende doch was anderes gefragt hat. ) Insbesondere auch, weil so was ähnliches in Python2 ja erlaubt war: Tuple unpacking in Signaturen:
Man könnte erfordern, dass diese Art von Parametern positional-only ist, weil es keine richtige Syntax gibt (bzw. geben kann), um den Namen beim Aufruf anzugeben.
Für `inspect` könnte man entweder sagen, dass der Parameter keinen Namen hat (Wozu braucht ein positional-only-Parameter einen Namen? Und nicht alle Callables haben `inspect`able Signaturen, z. B. wenn sie in C geschrieben sind.) oder es könnte das, was tatsächlich im Quelltext steht, als Parametername genommen werden. Also bei `def f((xs + ys)[42 + 27]): pass` wäre der Name dann `(xs + ys)[42 + 27]`. Zeichenkette ist Zeichenkette, würde sich dadurch also wirklich Code verkomplizieren?
Und für welchen Gewinn? Keine Ahnung, aber ich fand die Frage nachvollziehbar, warum das nicht erlaubt ist, weil es eine scheinbar willkürliche Restriktion ist. (Auch wenn die Frage am Ende doch was anderes gefragt hat. ) Insbesondere auch, weil so was ähnliches in Python2 ja erlaubt war: Tuple unpacking in Signaturen:
Code: Alles auswählen
>>>> def f((a, b), (c, d), **e):
.... pass
....
>>>> inspect.getargspec(f)
ArgSpec(args=[['a', 'b'], ['c', 'd']], varargs=None, keywords='e', defaults=None)
Vermutlich weil es keinen Sinn hat. Nichts in dieser Diskussion konnte mir bisher vermitteln, dass so etwas eine intelligente Lösung für was auch immer wäre.
- __blackjack__
- User
- Beiträge: 13131
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@narpfel: Ich weiss nicht ob ich das als willkürliche Restriktion bezeichnen würde. Das wäre es wenn es eigentlich schon implementiert ist und dann zusätzlicher Code das verhindert. Hier ist es ja anders herum: man müsste zusätzlich Code schreiben der das möglich machen würde.
Den Ausdruck einfach als Zeichenkette zu betrachten ist IMHO nicht sinnvoll/möglich. Denn "a[40 + 2]" und "a[42]" sind ja eigentlich gleich. Das es in C implementierte Funktionen gibt wo Positionsargumente keinen Namen haben ist richtig — und richtig scheisse, weil da bestimmte Sachen wie `functools.partial()` mit Namen und ``**`` bei Aufruf nicht funktionieren. Da will man weniger von, nicht noch mehr.
Den Ausdruck einfach als Zeichenkette zu betrachten ist IMHO nicht sinnvoll/möglich. Denn "a[40 + 2]" und "a[42]" sind ja eigentlich gleich. Das es in C implementierte Funktionen gibt wo Positionsargumente keinen Namen haben ist richtig — und richtig scheisse, weil da bestimmte Sachen wie `functools.partial()` mit Namen und ``**`` bei Aufruf nicht funktionieren. Da will man weniger von, nicht noch mehr.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis