Tại sao các đối số không mặc định theo các đối số mặc định?


137

Tại sao đoạn mã này ném 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

Trong khi đoạn mã sau chạy mà không có lỗi hiển thị:

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

trong python đó là cách cấu trúc khi bạn xác định hàm def myfunction(position_arguments, *arguments, **keywords):`....`
abhishekgarg

Câu trả lời:


172

Tất cả các tham số bắt buộc phải được đặt trước bất kỳ đối số mặc định. Đơn giản vì chúng là bắt buộc, trong khi các đối số mặc định thì không. Về mặt cú pháp, người phiên dịch sẽ không thể quyết định giá trị nào khớp với đối số nào nếu chế độ hỗn hợp được cho phép. MộtSyntaxError được nêu lên nếu các đối số không được đưa ra theo đúng thứ tự:

Chúng ta hãy xem các đối số từ khóa, sử dụng chức năng của bạn.

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

Giả sử hàm được phép khai báo như trên, sau đó với các khai báo ở trên, chúng ta có thể thực hiện các cuộc gọi đối số từ khóa hoặc vị trí (thông thường) sau:

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

Làm thế nào bạn sẽ đề xuất việc gán các biến trong lệnh gọi hàm, cách các đối số mặc định sẽ được sử dụng cùng với các đối số từ khóa.

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

Tham khảo O'Reilly - Core-Python
Khi hàm này sử dụng các đối số mặc định đúng về mặt cú pháp cho các lệnh gọi hàm trên. Gọi đối số từ khóa hữu ích để có thể cung cấp cho các đối số vị trí không theo thứ tự, nhưng, cùng với các đối số mặc định, chúng cũng có thể được sử dụng để "bỏ qua" các đối số bị thiếu.


3
<q> Về mặt cú pháp, người phiên dịch sẽ không thể quyết định giá trị nào khớp với đối số nào nếu chế độ hỗn hợp được cho phép. </ q> Ruby cho phép các đối số không mặc định theo sau các đối số mặc định. <q> Cách bạn sẽ đề xuất việc gán biến trong lệnh gọi hàm </ q> Chỉ cần sử dụng func1(x=1, y=2).
yếu

Xin chào @weakish, cảm ơn vì nhận xét, Python có một cách hay để đạt được điều này, Vui lòng tìm kiếm * args và ** kwargs
Rahul Gautam

Xin chào @Rahul Gautam Tôi đang bối rối. Tôi nghĩ rằng **kwargskhông thể làm def fun1(a="who is you", b="True", x, y)hoặc tương tự làm việc. Nếu bạn sử dụng def f(**kwargs), bạn cần xử lý các giá trị mặc định trong cơ thể?
yếu

@weakish def fun1(a="who is you", b="True", x, y)điều tương tự đạt được với một phong cách khác nhau. if def fun1 (** kwrss) `thì gọi fun1({'a': 'who is you', 'b': True})không cần truyền x và y.
Rahul Gautam

1
Tại sao bạn viết "Cú pháp, người phiên dịch sẽ không thể quyết định giá trị nào khớp với đối số nào nếu chế độ hỗn hợp được cho phép."? Tôi nghĩ rằng thuật toán tại PEP 3102 có thể hoạt động chính xác như nhau ngay cả khi def foo(x=None, y)được phép. Vì vậy, tôi vẫn tò mò tại sao điều này không được Python cho phép. Có một lý do cơ bản thực sự hay chỉ là "chúng tôi không cho phép vì chúng tôi không cho phép".
Jeroen Demeyer

15
SyntaxError: non-default argument follows default argument

Nếu bạn cho phép điều này, các đối số mặc định sẽ được hiển thị vô dụng vì bạn sẽ không bao giờ có thể sử dụng các giá trị mặc định của chúng, vì các đối số không mặc định xuất hiện sau .

Tuy nhiên, trong Python 3, bạn có thể làm như sau:

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

mà chỉ xytừ khóa để bạn có thể làm điều này:

fun1(x=2, y=2)

Điều này hoạt động vì không còn bất kỳ sự mơ hồ. Lưu ý bạn vẫn không thể làm fun1(2, 2)(điều đó sẽ đặt các đối số mặc định).


Các đối số chỉ có từ khóa là một tính năng gọn gàng của Python 3. Thật tệ khi bản vá để backport chúng vào Python 2.6 và 2.7 chỉ còn lại để hết hạn .
Nick Chammas

10

Hãy để tôi xóa hai điểm ở đây:

  • đầu tiên đối số không mặc định không nên tuân theo đối số mặc định, điều đó có nghĩa là bạn không thể xác định (a = b, c) trong hàm theo thứ tự xác định tham số trong hàm là:
    • tham số vị trí hoặc tham số không mặc định tức là (a, b, c)
    • tham số từ khóa hoặc tham số mặc định tức là (a = "b", r = "j")
    • tham số chỉ từ khóa tức là (* args)
    • tham số var-keyword tức là (** kwargs)

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

(a, b) là tham số vị trí

(c = none) là tham số tùy chọn

(r = "w") là tham số từ khóa

(d = []) là tham số danh sách

(* ae) là từ khóa duy nhất

(** ab) là tham số var-keyword

  • Bây giờ điều thứ hai là nếu tôi thử một cái gì đó như thế này: def example(a, b, c=a,d=b):

đối số không được xác định khi lưu giá trị mặc định, Python tính toán và lưu giá trị mặc định khi bạn xác định hàm

c và d không được xác định, không tồn tại, khi điều này xảy ra (nó chỉ tồn tại khi hàm được thực thi)

"a, a = b" không được phép trong tham số.


0

Các đối số bắt buộc (những đối số không có mặc định), phải ở đầu để cho phép mã máy khách chỉ cung cấp hai. Nếu các đối số tùy chọn là lúc bắt đầu, nó sẽ gây nhầm lẫn:

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

Điều đó sẽ làm gì trong ví dụ đầu tiên của bạn? Cuối cùng, x là "ai là ai", y là 3 và a = "jack".

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.