Adakah yang bisa menjelaskan alasan konkret mengapa BDFL memilih untuk membuat Python lambdas satu baris?
Ini bagus:
lambda x: x**x
Ini menghasilkan kesalahan:
lambda x:
x**x
Saya mengerti bahwa membuat lambda multi-baris entah bagaimana akan "mengganggu" aturan lekukan normal dan akan membutuhkan menambahkan lebih banyak pengecualian, tetapi bukankah itu sepadan dengan manfaatnya?
Lihatlah JavaScript, misalnya. Bagaimana seseorang bisa hidup tanpa fungsi-fungsi anonim itu? Mereka sangat diperlukan. Bukankah Pythonistas ingin menyingkirkan keharusan untuk menamai setiap fungsi multi-line hanya untuk melewatinya sebagai argumen?
def
? Sekarang memiliki struktur visual yang persis sama.Jawaban:
Guido van van Rossum menjawab sendiri:
http://www.artima.com/weblogs/viewpost.jsp?thread=147358
Pada dasarnya, dia mengatakan bahwa meskipun solusi mungkin, itu tidak sesuai dengan bagaimana Python.
sumber
tidak apa-apa untuk melakukan multi-baris lambda di python: lihat
batasan lambda yang sebenarnya adalah fakta bahwa lambda harus merupakan ungkapan tunggal ; tidak dapat berisi kata kunci (seperti python2
print
ataureturn
).GvR memilih untuk melakukannya untuk membatasi ukuran lambda, karena biasanya digunakan sebagai parameter. Jika Anda ingin fungsi yang sebenarnya, gunakan
def
sumber
def
. Pikirkan tentang hal ini: Anda benar-benar perlu dipanggil sebagai parameter fungsi Anda? Dan pengguna fungsi itu tidak diizinkan melewati panggilan default Anda ? Bagaimana mereka bisa lulus jika Anda tidak memberikannya kepada mereka?Saya tahu ini sangat tua, tetapi menempatkan di sini sebagai referensi.
Alternatif untuk menggunakan lambda bisa dengan menggunakan
def
cara non-konvensional. Tujuannya adalah untuk meneruskandef
fungsi, yang dapat dilakukan hanya dalam satu keadaan - dekorator. Perhatikan bahwa dengan implementasidef result
ini tidak membuat fungsi, itu menciptakan hasilreduce()
, yang akhirnya menjadi adict
.Steker tak tahu malu : Saya melakukan banyak hal di sini .
Perhatikan bahwa multi-pernyataan lambdas dapat dilakukan, tetapi hanya dengan kode yang benar-benar jelek. Namun, yang menarik adalah bagaimana pelingkupan bekerja dengan implementasi ini (perhatikan penggunaan beragam
name
variabel dan bayanganmessage
variabel.sumber
Meretas bersama-sama lambda multi-pernyataan tidak seburuk yang dibuat oleh pyrospade: yakin kita bisa membuat banyak fungsi monadik menggunakan bind, seperti di Haskell, tapi karena kita berada di dunia Python yang tidak murni, kita juga bisa gunakan efek samping untuk mencapai hal yang sama.
Saya membahas beberapa cara untuk melakukan ini di blog saya .
Sebagai contoh, Python menjamin untuk mengevaluasi elemen tuple secara berurutan, sehingga kita dapat menggunakan
,
banyak seperti perintah;
. Kami dapat mengganti banyak pernyataan, sepertiprint
, dengan ekspresi, sepertisys.stdout.write
.Karenanya berikut ini setara:
Perhatikan bahwa saya telah menambahkan
None
di bagian akhir, dan mengekstraknya menggunakan[-1]
; ini menetapkan nilai kembali secara eksplisit. Kita tidak harus melakukan ini, tetapi tanpanya kita akan mendapatkan(None, None, None)
nilai pengembalian yang funky , yang mungkin atau mungkin tidak kita pedulikan.Jadi kita bisa mengurutkan tindakan IO. Bagaimana dengan variabel lokal?
Python
=
membentuk pernyataan, jadi kita perlu menemukan ekspresi yang setara. Salah satu caranya adalah dengan memutasi konten struktur data, diteruskan sebagai argumen. Sebagai contoh:Ada beberapa trik yang digunakan di
stateful_lambda
:*_
argumen memungkinkan lambda kami untuk mengambil setiap jumlah argumen. Karena ini memungkinkan nol argumen, kami memulihkan konvensi pemanggilanstateful_def
._
hanyalah konvensi yang mengatakan "Saya tidak akan menggunakan variabel ini"lambda state: lambda *_: ...
(lambda state: ...)({})
state
ke nilai{}
tanpa menggunakan pernyataan penugasan (mis.state = {}
)state
sebagai nama variabel dan nilai terikatstate.setdefault(a, b)
bukannyaa = b
danstate.get(a)
bukannyaa
[-1]
untuk mengekstrak nilai terakhir, yang bertindak sepertireturn
pernyataanTentu saja ini cukup rumit, tetapi kita bisa membuat API yang lebih bagus dengan fungsi pembantu:
sumber
Saya pikir saya bisa berkontribusi, gunakan line breaker:
Jangan lupa hal yang sangat bagus yang bisa ditulis oleh python pada orang-orang yang tidak bertanggung jawab, seperti dalam contoh:
Dan lambda sangat kuat, tetapi itu tidak dimaksudkan untuk menggantikan seluruh fungsi, maksud saya Anda dapat meretasnya seperti (meminjam contoh dari kolega di atas):
Tetapi apakah Anda benar-benar ingin melakukannya seperti ini? Ini sebagian besar tidak dapat dibaca setelah beberapa waktu, itu seperti sampai ke awal tali dimulai dengan ujung yang tidak terurai.
Lambdas disebut sebagai fungsi satu-satunya, dalam peta, memfilter dan mengurangi fungsi dalam Pemrograman Berorientasi Fungsional (antara lain). Misalnya mendapatkan nilai karakter dari nilai yang integer dan habis dibagi 2
Anda bisa menggunakannya sebagai fungsi ekspresi fungsi dengan mendifinisikan fungsi kompleks (atau lebih dan beberapa lambda, dan meletakkannya di dalam lambda lain:
tetapi Python memiliki dukungan fungsi expresi dengan cara lain: -lets mengatakan Anda memiliki beberapa fungsi yang dipanggil
superAwesomeFunction
dan fungsi itu dapat melakukan beberapa hal yang sangat mengagumkan, Anda dapat menetapkannya ke variabel dengan tidak memanggilnya, seperti ini:Jadi sekarang ketika Anda memanggil SAF Anda akan memanggil superAwesomeFunction atau metode. Jika Anda mencari melalui folder Lib Anda, Anda dapat menemukan bahwa sebagian besar
__builtin__
modul python ditulis seperti itu. Ini dilakukan karena kadang-kadang Anda akan memerlukan beberapa fungsi yang melakukan tugas tertentu yang tidak cukup untuk dapat digunakan oleh pengguna tetapi diperlukan untuk beberapa fungsi. Jadi Anda memiliki pilihan, Anda tidak dapat memiliki 2 fungsi dengan nama "superAwesomeFunction", Anda dapat memiliki "superAwesomeFunctionDoingBasicStuf" dan "realSuperAwesomeFunction" dan daripada hanya meletakkan "realSuperAwesomeFunction" pada variabel "superAwesomeFunction" dan Anda selesai.Anda dapat menemukan lokasi modul yang diimpor dengan memasukkan di konsol
importedModule.__file__
(contoh nyataimport os;os.__file__
), dan cukup ikuti direktori itu ke file yang disebut importModule.py dan buka di editor dan temukan bagaimana Anda dapat memaksimalkan "pengetahuan" Anda sendiri.Saya harap ini membantu Anda dan mungkin rekan kerja lain yang bermasalah.
sumber