Tên của ** trong python là gì?


59

Khi lập trình Python đôi khi tôi **thực hiện một chuyển đổi. Tôi hiểu những gì nó làm nhưng những gì tôi đang thao tác cấu trúc dữ liệu? A dictvà cái kia là gì? An array? Có một tên cho các **nhà điều hành?


3
Toán tử mũ?
Rook

12
Có hai ý nghĩa cho **. Sức mạnh và "từ điển đối số từ khóa". Bạn đang nói về cái gì Tài liệu này có các từ sau: "Nếu có mẫu Nhận dạng ** **, nó được khởi tạo cho một từ điển mới nhận bất kỳ đối số từ khóa dư thừa nào, mặc định là một từ điển trống mới." Cái nào trong số chúng có vẻ phù hợp với câu hỏi của bạn?
S.Lott

"Từ điển đối số từ khóa" là từ mà tôi đang hỏi về. Cảm ơn bạn đã cho ý kiến.
Niklas Rosencrantz

Câu trả lời:


86

Nó không phải là một toán tử như vậy, vì vậy nó không thực sự có tên, nhưng nó được định nghĩa là "quy tắc cú pháp" . Vì vậy, nó nên được gọi là:

  • "cú pháp giải nén từ khóa"

Nếu bạn có một danh sách các đối số, *argsthì nó được gọi là "giải nén đối số" , theo cách tương tự **kwargsđược gọi là "giải nén đối số từ khóa" .

Nếu bạn sử dụng nó ở phía bên trái của một =, như trong a, *middle, end = my_tuple, bạn sẽ nói "tuple unpacking" .

Tổng cộng, có ba loại đối số (tham số đơn):

def f(x)  # x: positional argument
def f(x, y=0)  # y: keyword argument
def f(x, *xs, y=0)  # y: keyword-only argument

Đối *argssố được gọi là "tham số vị trí biến" và **kwargslà "tham số từ khóa biến". Các đối số chỉ từ khóa không thể được đưa ra theo vị trí, bởi vì một tham số vị trí thay đổi sẽ lấy tất cả các đối số bạn vượt qua.

Hầu hết điều này có thể được tìm thấy trong PEP 03623102 , cũng như trong phần Dòng điều khiển của tài liệu. Cần lưu ý rằng mặc dù đối tượng chữ ký hàm PEP chỉ là một bản nháp và thuật ngữ có thể chỉ là ý tưởng của một người. Nhưng dù sao họ cũng là những điều khoản tốt. :)

Vì vậy, *và các **đối số chỉ giải nén cấu trúc dữ liệu tương ứng của chúng:

args = (1, 2, 3)  # usually a tuple, always an iterable[1]

f(*args)  f(1, 2, 3)

# and 

kwargs = {"a": 1, "b": 2, "c": 3}  # usually a dict, always a mapping*

f(**kwargs) -> f(a=1, b=2, c=3)

[1]: Iterables là các đối tượng thực hiện __iter__()phương thức và ánh xạ là các đối tượng thực hiện keys()__getitem__(). Bất kỳ đối tượng nào hỗ trợ giao thức này sẽ được các nhà xây dựng hiểu tuple()dict()vì vậy chúng có thể được sử dụng để giải nén các đối số.


3
Trong trường hợp bất kỳ ai khác bị nhầm lẫn, def f(x, *xs, y=0): passcú pháp Python 2. {5,6,7} không hợp lệ, cũng không def f(x, y=0, *xs):làm những gì bạn có thể mong đợi. AFAIK, cách duy nhất để đạt được hiệu quả (rõ ràng) dự định là def f(x, *xs, **kw): y=kw.get('y', 0); del kw; .... Python 3 xử lý cú pháp ban đầu như mong đợi.
chbrown

1
Trong khi chúng ta đang ở đó: begin, *middle, end = (0, 1, 2, 3, 4, 5)cú pháp cũng không hoạt động trong Python 2.x.
Stefano Palazzo

Câu trả lời này không chính xác trong Python 3.5 trở lên. PEP-448 chỉ định toán tử ** là toán tử giải nén từ điển. Xem python.org/dev/peps/pep-0448
devnul3

13

Tôi không nghĩ nó có tên. Trong Tài liệu Python trong "Danh sách đối số giải nén", nó chỉ được gọi là "Trình điều khiển" **.

Tôi không chắc ý của bạn về cấu trúc dữ liệu "khác". Khi bạn f(**kwargs)giải nén từ điển kwargsdưới dạng một chuỗi các cặp khóa-giá trị. Tôi không thấy rằng có một cấu trúc khác liên quan.

Tôi sẽ sao chép ví dụ trong tài liệu trên cho rõ ràng.

>>> def parrot(voltage, state='a stiff', action='voom'):
...     print "-- This parrot wouldn't", action,
...     print "if you put", voltage, "volts through it.",
...     print "E's", state, "!"
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !

Xem thêm: * args và ** kwargs có nghĩa là gì?


Có một số cách mà người đọc có thể diễn giải f(**kwargs)...
Deer Hunter

3

Nếu bạn không chắc chắn nên gọi một nhà điều hành cụ thể hoặc nếu nó không được đặt tên, bạn luôn có thể sử dụng Waka Waka Bang Splat như một tài liệu tham khảo để giúp bạn tìm ra cách gọi nó. Trong trường hợp này **tôi sẽ gọi nó double-splat, mặc dù có một số tên thay thế cho các biểu tượng .

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.