Trong khi hầu hết các câu trả lời đang nói rằng, ví dụ,
def f(**kwargs):
foo = kwargs.pop('foo')
bar = kwargs.pop('bar')
...etc...
là "giống như"
def f(foo=None, bar=None, **kwargs):
...etc...
Đây không phải là sự thật. Trong trường hợp sau, f
có thể được gọi là f(23, 42)
, trong khi các trường hợp trước đây chấp nhận tên đối số duy nhất - không có cuộc gọi vị trí. Thường thì bạn muốn cho phép người gọi linh hoạt tối đa và do đó, hình thức thứ hai, như hầu hết các câu trả lời khẳng định, là thích hợp hơn: nhưng điều đó không phải lúc nào cũng đúng. Khi bạn chấp nhận nhiều tham số tùy chọn trong đó thường chỉ có một vài thông số được thông qua, đó có thể là một ý tưởng tuyệt vời (tránh tai nạn và mã không thể đọc được tại các trang web cuộc gọi của bạn!) Để buộc sử dụng các đối số được đặt tên - threading.Thread
là một ví dụ. Hình thức đầu tiên là cách bạn triển khai nó trong Python 2.
Các thành ngữ là quan trọng đến nỗi bằng Python 3 nó bây giờ có cú pháp hỗ trợ đặc biệt: mọi lý luận sau khi một đơn *
trong def
chữ ký là từ khóa mà thôi, có nghĩa là, không thể được thông qua như là một đối số vị trí, nhưng chỉ như một tên. Vì vậy, trong Python 3, bạn có thể mã ở trên là:
def f(*, foo=None, bar=None, **kwargs):
...etc...
Thật vậy, trong Python 3, bạn thậm chí có thể có các đối số chỉ từ khóa không phải là tùy chọn (những đối số không có giá trị mặc định).
Tuy nhiên, Python 2 vẫn còn nhiều năm hoạt động lâu dài, vì vậy tốt hơn hết là đừng quên các kỹ thuật và thành ngữ cho phép bạn thực hiện trong Python 2 ý tưởng thiết kế quan trọng được hỗ trợ trực tiếp bằng ngôn ngữ trong Python 3!