Untuk apa simbol '@ =' dalam Python?

173

Saya tahu @ini untuk dekorator, tapi untuk apa @=Python? Apakah hanya reservasi untuk beberapa ide masa depan?

Ini hanya salah satu dari banyak pertanyaan saya saat membaca tokenizer.py.

Octavia Togami
sumber
1
Lihat cset c553d8f72d65 ( mirror GitHub ... lebih mudah dibaca ) di repo CPython.
Nick T
SymbolHound adalah mesin pencari yang dapat mencari pada simbol tanda baca. Namun mencari @ = python saat ini tidak memberikan hasil yang relevan, karena dokumentasi Python 3.5 berisi '@' tetapi bukan contoh '@ =' di mana saja. Saya mengirim pesan kepada SH untuk membantu meningkatkannya. Python doc juga bisa meningkat.
smci
1
Dikombinasikan dengan := operator walrus dari Python 3.8, Anda mendapatkan apa yang dikenal sebagai @:=operator rose berduri. (Atau di Jepang itu dikenal sebagai operator Elvis-walrus.)
Bob Stein

Jawaban:

185

Dari yang dokumentasi :

Operator @(at) dimaksudkan untuk digunakan untuk perkalian matriks. Tidak ada tipe Python bawaan yang mengimplementasikan operator ini.

The @Operator diperkenalkan dengan Python 3.5. @=adalah perkalian matriks yang diikuti oleh penugasan, seperti yang Anda harapkan. Mereka memetakan __matmul__, __rmatmul__atau __imatmul__mirip dengan bagaimana +dan +=memetakan __add__, __radd__atau __iadd__.

Operator dan alasan di baliknya dibahas secara rinci dalam PEP 465 .

sayap kanan
sumber
12
Itu menjelaskan mengapa ini ada di versi terbaru tokenizer.py tetapi tidak pada 3.4 docs.
Octavia Togami
10
Ini dicakup dalam dokumen 3.5's - docs.python.org/3.5/reference/… dan docs.python.org/3.5/reference/…
jonrsharpe
Apakah ini memiliki konflik dengan dekorator Python? Ini tidak diimplementasikan dalam Python 2.n, kan?
frankliuao
4
Ini tidak bertentangan dengan dekorator, karena dekorator mungkin tidak pernah didahului oleh ekspresi, dan operator biner harus selalu didahului oleh ekspresi.
sayap kanan
58

@=dan @operator baru diperkenalkan di Python 3.5 melakukan perkalian matriks . Mereka dimaksudkan untuk mengklarifikasi kebingungan yang ada sejauh ini dengan operator *yang digunakan baik untuk perkalian elemen-bijaksana atau perkalian matriks tergantung pada konvensi yang digunakan dalam perpustakaan / kode tertentu. Akibatnya, di masa depan, operator *dimaksudkan hanya untuk penggandaan elemen-bijaksana.

Sebagaimana dijelaskan dalam PEP0465 , dua operator diperkenalkan:

  • Operator biner baru A @ B, digunakan sama sepertiA * B
  • Versi di tempat A @= B, digunakan sama sepertiA *= B

Perkalian Matriks vs Perkalian Elemen-bijaksana

Untuk dengan cepat menyoroti perbedaannya, untuk dua matriks:

A = [[1, 2],    B = [[11, 12],
     [3, 4]]         [13, 14]]
  • Penggandaan elemen-bijaksana akan menghasilkan:

    A * B = [[1 * 11,   2 * 12], 
             [3 * 13,   4 * 14]]
    
  • Multiplikasi matriks akan menghasilkan:

    A @ B  =  [[1 * 11 + 2 * 13,   1 * 12 + 2 * 14],
               [3 * 11 + 4 * 13,   3 * 12 + 4 * 14]]
    

Penggunaan di Numpy

Sejauh ini, Numpy menggunakan konvensi berikut:

Pengenalan @operator membuat kode yang melibatkan perkalian matriks lebih mudah dibaca. PEP0465 memberi kita contoh:

# Current implementation of matrix multiplications using dot function
S = np.dot((np.dot(H, beta) - r).T,
            np.dot(inv(np.dot(np.dot(H, V), H.T)), np.dot(H, beta) - r))

# Current implementation of matrix multiplications using dot method
S = (H.dot(beta) - r).T.dot(inv(H.dot(V).dot(H.T))).dot(H.dot(beta) - r)

# Using the @ operator instead
S = (H @ beta - r).T @ inv(H @ V @ H.T) @ (H @ beta - r)

Jelas, implementasi terakhir jauh lebih mudah dibaca dan ditafsirkan sebagai sebuah persamaan.

Andrzej Pronobis
sumber
11
Hanya untuk klarifikasi: dari contoh pertama Anda, kami dapat berpikir bahwa @telah diterapkan untuk list, yang tidak terjadi.
Conchylicultor
1
@dikaitkan dengan np.matmul, bukan np.dot. Keduanya serupa tetapi tidak sama.
Acumenus
@ ABB, mungkin Anda bisa memberikan contoh mengklarifikasi nuansa dan memastikan jawabannya selesai?
benjaminmgross