Mengapa argumen non-default tidak dapat mengikuti argumen default?

137

Mengapa kode ini melempar 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

Sementara potongan kode berikut ini berjalan tanpa kesalahan yang terlihat:

>>> def fun1(x, y, a="who is you", b="True"):
...     print a,b,x,y
... 
dotslash
sumber
dalam python itulah bagaimana strukturnya ketika Anda mendefinisikan fungsi def myfunction(position_arguments, *arguments, **keywords):`....`
abhishekgarg

Jawaban:

172

Semua parameter yang diperlukan harus ditempatkan sebelum argumen default apa pun. Hanya karena mereka wajib, sedangkan argumen default tidak. Secara sintaksis, tidak mungkin bagi juru bahasa untuk memutuskan nilai mana yang cocok dengan argumen mana jika mode campuran diizinkan. A SyntaxErrordimunculkan jika argumen tidak diberikan dalam urutan yang benar:

Mari kita lihat argumen kata kunci, menggunakan fungsi Anda.

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

Misalkan diizinkan untuk mendeklarasikan fungsi seperti di atas, Kemudian dengan deklarasi di atas, kita dapat melakukan panggilan argumen posisi atau kata kunci berikut:

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

Bagaimana Anda akan menyarankan penugasan variabel dalam panggilan fungsi, bagaimana argumen default akan digunakan bersama dengan argumen kata kunci.

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

Referensi O'Reilly - Core-Python
Dimana fungsi ini memanfaatkan argumen default yang benar secara sintaksis untuk panggilan fungsi di atas. Panggilan argumen kata kunci terbukti bermanfaat untuk dapat memberikan argumen posisi yang tidak sesuai pesanan, tetapi, ditambah dengan argumen default, argumen tersebut juga dapat digunakan untuk "melewatkan" argumen yang hilang juga.

Rahul Gautam
sumber
4
<q> Secara sintaksis, tidak mungkin bagi juru bahasa untuk memutuskan nilai mana yang cocok dengan argumen mana jika mode campuran diizinkan. </q> Ruby memungkinkan argumen non-default mengikuti yang default. <q> Bagaimana Anda akan menyarankan penetapan variabel dalam panggilan fungsi </q> Cukup gunakan func1(x=1, y=2).
lemah
Hai @weakish, terima kasih atas komentarnya, Python memang memiliki cara yang bagus untuk mencapai hal ini, Silakan cari * args dan ** kwargs
Rahul Gautam
Hai @Rahul Gautam saya bingung. Saya pikir **kwargstidak bisa membuat def fun1(a="who is you", b="True", x, y)atau bekerja serupa. Jika Anda menggunakan def f(**kwargs), Anda perlu menangani nilai default di dalam tubuh?
lemah
@weakish def fun1(a="who is you", b="True", x, y)hal yang sama diraih dengan gaya yang berbeda. jika def fun1 (** kwrgs) `maka panggil fun1({'a': 'who is you', 'b': True})tidak perlu lewat x dan y.
Rahul Gautam
2
Mengapa Anda menulis "Secara sintaksis, tidak mungkin bagi juru bahasa untuk memutuskan nilai mana yang cocok dengan argumen mana jika mode campuran diizinkan."? Saya berpikir bahwa algoritma di PEP 3102 dapat bekerja sama persis meskipun def foo(x=None, y)akan diizinkan. Jadi saya masih penasaran mengapa ini tidak diizinkan oleh Python. Apakah ada alasan mendasar yang sebenarnya atau hanya "kami tidak mengizinkannya karena kami tidak mengizinkannya".
Jeroen Demeyer
15
SyntaxError: non-default argument follows default argument

Jika Anda mengizinkan ini, argumen default akan dianggap tidak berguna karena Anda tidak akan pernah dapat menggunakan nilai defaultnya, karena argumen non-default akan muncul setelahnya .

Namun dalam Python 3, Anda dapat melakukan hal berikut:

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

yang membuat xdan yhanya kata kunci sehingga Anda dapat melakukan ini:

fun1(x=2, y=2)

Ini bekerja karena tidak ada lagi ambiguitas. Catatan Anda masih tidak dapat melakukan fun1(2, 2)(yang akan menetapkan argumen default).

jamylak
sumber
Argumen hanya kata kunci adalah fitur rapi dari Python 3. Sayang sekali tambalan untuk mendukung mereka ke Python 2.6 dan 2.7 hanya tersisa untuk kedaluwarsa .
Nick Chammas
10

Biarkan saya menghapus dua poin di sini:

  • pertama argumen non-default tidak boleh mengikuti argumen default, itu berarti Anda tidak dapat mendefinisikan (a = b, c) dalam fungsi urutan parameter dalam fungsi adalah:
    • parameter posisi atau parameter non-standar yaitu (a, b, c)
    • parameter kata kunci atau parameter default yaitu (a = "b", r = "j")
    • parameter hanya kata kunci (* args)
    • parameter kata kunci var (** kwargs)

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

(a, b) adalah parameter posisi

(c = tidak ada) adalah parameter opsional

(r = "w") adalah parameter kata kunci

(d = []) adalah parameter daftar

(* ae) hanya untuk kata kunci

(** ab) adalah parameter var-keyword

  • sekarang hal kedua adalah jika saya mencoba sesuatu seperti ini: def example(a, b, c=a,d=b):

argumen tidak ditentukan ketika nilai-nilai default disimpan, Python menghitung dan menyimpan nilai-nilai default ketika Anda mendefinisikan fungsi

c dan d tidak didefinisikan, tidak ada, ketika ini terjadi (itu hanya ada ketika fungsi dijalankan)

"a, a = b" tidak diizinkan dalam parameter.

Aaditya Ura
sumber
0

Argumen yang diperlukan (yang tanpa default), harus di awal untuk memungkinkan kode klien hanya memasok dua. Jika argumen opsional ada di awal, itu akan membingungkan:

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

Apa yang akan dilakukan dalam contoh pertama Anda? Yang terakhir, x adalah "who is who", y adalah 3 dan a = "jack".

cforbish
sumber