Saya baru-baru ini menemukan sintaks yang tidak pernah saya lihat sebelumnya ketika saya belajar python atau dalam kebanyakan tutorial, ..
notasinya, terlihat seperti ini:
f = 1..__truediv__ # or 1..__div__ for python 2
print(f(8)) # prints 0.125
Saya pikir itu persis sama dengan (kecuali tentu saja lebih lama):
f = lambda x: (1).__truediv__(x)
print(f(8)) # prints 0.125 or 1//8
Tapi pertanyaan saya adalah:
- Bagaimana itu bisa dilakukan?
- Apa sebenarnya yang dimaksud dengan dua titik?
- Bagaimana Anda bisa menggunakannya dalam pernyataan yang lebih kompleks (jika mungkin)?
Ini mungkin akan menyelamatkan saya banyak baris kode di masa depan ... :)
(1).__truediv__
tidak benar-benar sama dengan1..__truediv__
, seperti panggilan sebelumnyaint.__truediv__
sedangkan yang terakhir tidakfloat.__truediv__
. Atau, Anda juga dapat menggunakan1 .__truediv__
(dengan spasi) `1//8
adalah0
, tidak0.125
, baik dalam versi Python.if (x <- 3) {...}
Jawaban:
Apa yang Anda miliki adalah
float
literal tanpa nol tambahan, yang kemudian Anda akses__truediv__
metode. Itu bukan operator itu sendiri; titik pertama adalah bagian dari nilai float, dan yang kedua adalah operator titik untuk mengakses properti objek dan metode.Anda dapat mencapai titik yang sama dengan melakukan hal berikut.
Contoh lain
Di sini kita menambahkan 1,0 hingga 2,0, yang jelas menghasilkan 3,0.
sumber
1..toString()
Pertanyaannya sudah cukup dijawab (yaitu jawaban @Paul Rooney ) tetapi juga mungkin untuk memverifikasi kebenaran jawaban ini.
Biarkan saya rekap jawaban yang ada: Ini
..
bukan elemen sintaks tunggal!Anda dapat memeriksa bagaimana kode sumber "tokenized" . Token ini menunjukkan bagaimana kode ditafsirkan:
Jadi string
1.
ditafsirkan sebagai angka, yang kedua.
adalah OP (operator, dalam hal ini operator "dapatkan atribut") dan__truediv__
adalah nama metode. Jadi ini hanya mengakses__truediv__
metode float1.0
.Cara lain untuk melihat bytecode yang dihasilkan adalah dengan merakitnya . Ini sebenarnya menunjukkan instruksi yang dilakukan ketika beberapa kode dijalankan:
dis
Yang pada dasarnya mengatakan hal yang sama. Ini memuat atribut
__truediv__
dari konstanta1.0
.Mengenai pertanyaan Anda
Meskipun mungkin Anda tidak boleh menulis kode seperti itu, hanya karena tidak jelas apa yang dilakukan kode. Jadi tolong jangan menggunakannya dalam pernyataan yang lebih kompleks. Saya bahkan akan melangkah lebih jauh sehingga Anda tidak boleh menggunakannya dalam pernyataan yang begitu "sederhana", setidaknya Anda harus menggunakan tanda kurung untuk memisahkan instruksi:
ini akan lebih mudah dibaca - tetapi sesuatu seperti:
akan lebih baik!
Pendekatan menggunakan
partial
juga mempertahankan model data python (1..__truediv__
pendekatan tidak!) Yang dapat ditunjukkan oleh potongan kecil ini:Ini karena
1. / (1+2j)
tidak dievaluasi olehfloat.__truediv__
tetapi dengancomplex.__rtruediv__
-operator.truediv
memastikan operasi mundur dipanggil ketika operasi normal kembaliNotImplemented
tetapi Anda tidak memiliki fallback ini ketika Anda beroperasi__truediv__
secara langsung. Hilangnya "perilaku yang diharapkan" ini adalah alasan utama mengapa Anda (biasanya) tidak harus menggunakan metode sihir secara langsung.sumber
Dua titik bersama mungkin agak canggung pada awalnya:
Tetapi sama dengan menulis:
Karena
float
literal dapat ditulis dalam tiga bentuk:sumber
1.__truediv__
tidak?.
tampaknya diurai sebagai bagian dari nomor tersebut, dan kemudian.
untuk metode accessor hilang.f
adalah metode khusus terikat pada float dengan nilai satu. Secara khusus,dalam Python 3, aktifkan:
Bukti:
dan:
Jika kita melakukannya:
Kami mempertahankan nama yang terikat pada metode terikat itu
Jika kami melakukan pencarian putus-putus itu dalam satu lingkaran ketat, ini bisa menghemat sedikit waktu.
Parsing Pohon Sintaksis Abstrak (AST)
Kita bisa melihat bahwa parsing AST untuk ekspresi memberitahu kita bahwa kita mendapatkan
__truediv__
atribut pada jumlah floating point,1.0
:Anda bisa mendapatkan fungsi hasil yang sama dari:
Atau
Deduksi
Kita juga bisa sampai di sana dengan deduksi.
Mari kita membangunnya.
1 dengan sendirinya adalah
int
:1 dengan periode setelahnya adalah pelampung:
Titik berikutnya dengan sendirinya akan menjadi SyntaxError, tapi itu memulai pencarian bertitik pada contoh float:
Tidak ada orang lain telah disebutkan ini - ini sekarang menjadi "metode terikat" pada float,
1.0
:Kita dapat melakukan fungsi yang sama dengan lebih mudah:
Performa
Kelemahan dari
divide_one_by
fungsi ini adalah bahwa ia membutuhkan bingkai tumpukan Python lain, membuatnya agak lebih lambat daripada metode terikat:Tentu saja, jika Anda bisa menggunakan literal biasa, itu bahkan lebih cepat:
sumber