Perché gli argomenti non predefiniti non possono seguire gli argomenti predefiniti?


137

Perché questo pezzo di codice genera un SyntaxError?

  >>> def fun1(a="who is you", b="True", x, y):
...     print a,b,x,y
... 
  File "<stdin>", line 1
SyntaxError: non-default argument follows default argument

Mentre il seguente pezzo di codice viene eseguito senza errori visibili:

>>> def fun1(x, y, a="who is you", b="True"):
...     print a,b,x,y
... 

in Python è così che è la struttura quando si definisce una funzione def myfunction(position_arguments, *arguments, **keywords):`....`
abhishekgarg

Risposte:


172

Tutti i parametri richiesti devono essere inseriti prima di qualsiasi argomento predefinito. Semplicemente perché sono obbligatori, mentre gli argomenti predefiniti no. Sintatticamente, sarebbe impossibile per l'interprete decidere quali valori corrispondono a quali argomenti se le modalità miste fossero consentite. A SyntaxErrorviene sollevato se gli argomenti non sono indicati nell'ordine corretto:

Diamo un'occhiata agli argomenti delle parole chiave, usando la tua funzione.

def fun1(a="who is you", b="True", x, y):
...     print a,b,x,y

Supponiamo che sia autorizzato a dichiarare la funzione come sopra, quindi con le dichiarazioni di cui sopra, possiamo effettuare le seguenti chiamate (regolari) di argomento posizionale o parola chiave:

func1("ok a", "ok b", 1)  # Is 1 assigned to x or ?
func1(1)                  # Is 1 assigned to a or ?
func1(1, 2)               # ?

Come suggerirai l'assegnazione delle variabili nella chiamata di funzione, come verranno utilizzati gli argomenti predefiniti insieme agli argomenti delle parole chiave.

>>> def fun1(x, y, a="who is you", b="True"):
...     print a,b,x,y
... 

Riferimento O'Reilly - Core-Python
Dove questa funzione utilizza gli argomenti predefiniti sintatticamente corretti per le chiamate di funzione sopra. La chiamata degli argomenti delle parole chiave si rivela utile per essere in grado di fornire argomenti posizionali fuori ordine, ma, insieme agli argomenti predefiniti, possono anche essere usati per "saltare" anche gli argomenti mancanti.


4
<q> Sintatticamente, sarebbe impossibile per l'interprete decidere quali valori corrispondono a quali argomenti se le modalità miste fossero consentite. </q> Ruby consente argomenti non predefiniti a seguito di quelli predefiniti. <q> Come suggerirai l'assegnazione delle variabili nella chiamata di funzione </q> Basta usare func1(x=1, y=2).
debole il

Ciao @weakish, grazie per il commento, Python ha un bel modo per raggiungere questo obiettivo, per favore vai a cercare * args e ** kwargs
Rahul Gautam il

Ciao @Rahul Gautam, sono confuso. Pensavo **kwargsnon potesse fare def fun1(a="who is you", b="True", x, y)o lavori simili. Se lo usi def f(**kwargs), devi gestire i valori predefiniti nel corpo?
debole il

@weakish si ottiene def fun1(a="who is you", b="True", x, y)la stessa cosa con uno stile diverso. if def fun1 (** kwrgs) `quindi chiama fun1({'a': 'who is you', 'b': True})non è necessario passare xey.
Rahul Gautam,

2
Perché scrivi "Sintatticamente, sarebbe impossibile per l'interprete decidere quali valori corrispondono a quali argomenti se le modalità miste fossero consentite."? Penso che l'algoritmo di PEP 3102 potrebbe funzionare esattamente allo stesso modo anche se def foo(x=None, y)fosse consentito. Quindi sono ancora curioso di sapere perché questo non è consentito da Python. C'è un vero motivo fondamentale o è solo "non lo permettiamo perché non lo permettiamo".
Jeroen Demeyer,

15
SyntaxError: non-default argument follows default argument

Se lo consentissi, gli argomenti predefiniti sarebbero resi inutili perché non potresti mai utilizzare i loro valori predefiniti, poiché gli argomenti non predefiniti vengono dopo .

In Python 3, tuttavia, puoi fare quanto segue:

def fun1(a="who is you", b="True", *, x, y):
    pass

che rende xe yparola chiave solo così puoi farlo:

fun1(x=2, y=2)

Questo funziona perché non c'è più alcuna ambiguità. Nota che non puoi ancora farlo fun1(2, 2)(che imposterebbe gli argomenti predefiniti).


Gli argomenti solo di parole chiave sono una caratteristica ordinata di Python 3. Peccato che la patch per riportarli in Python 2.6 e 2.7 fosse solo lasciata scadere .
Nick Chammas,

10

Vorrei chiarire due punti qui:

  • in primo luogo l'argomento non predefinito non deve seguire l'argomento predefinito, significa che non è possibile definire (a = b, c) in funzione l'ordine di definizione del parametro in funzione sono:
    • parametro posizionale o parametro non predefinito, ad es. (a, b, c)
    • parametro parola chiave o parametro predefinito ie (a = "b", r = "j")
    • parametro solo parola chiave ie (* args)
    • parametro var-keyword ie (** kwargs)

def example(a, b, c=None, r="w" , d=[], *ae, **ab):

(a, b) sono parametri posizionali

(c = none) è un parametro opzionale

(r = "w") è il parametro della parola chiave

(d = []) è il parametro list

(* ae) è solo una parola chiave

(** ab) è il parametro var-keyword

  • ora cosa secondaria è se provo qualcosa del genere: def example(a, b, c=a,d=b):

l'argomento non viene definito quando vengono salvati i valori predefiniti, Python calcola e salva i valori predefiniti quando si definisce la funzione

c e d non sono definiti, non esiste, quando ciò accade (esiste solo quando viene eseguita la funzione)

"a, a = b" non è ammesso nel parametro.


0

Gli argomenti richiesti (quelli senza valori predefiniti) devono essere all'inizio per consentire al codice client di fornire solo due. Se gli argomenti opzionali fossero all'inizio, sarebbe confuso:

fun1("who is who", 3, "jack")

Cosa farebbe nel tuo primo esempio? Nell'ultimo, x è "chi è chi", y è 3 e a = "jack".

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.