Saya mendapat peringatan pep8 ini setiap kali saya menggunakan ekspresi lambda. Apakah ungkapan lambda tidak disarankan? Jika tidak mengapa?
Saya mendapat peringatan pep8 ini setiap kali saya menggunakan ekspresi lambda. Apakah ungkapan lambda tidak disarankan? Jika tidak mengapa?
Jawaban:
Rekomendasi dalam PEP-8 yang Anda temui adalah:
Selalu gunakan pernyataan def alih-alih pernyataan tugas yang mengikat ekspresi lambda langsung ke nama.
Iya:
def f(x): return 2*x
Tidak:
f = lambda x: 2*x
Bentuk pertama berarti bahwa nama objek fungsi yang dihasilkan secara khusus 'f' bukan generik '<lambda>'. Ini lebih berguna untuk traceback dan representasi string secara umum. Penggunaan pernyataan penugasan menghilangkan satu-satunya manfaat ekspresi lambda dapat menawarkan lebih dari pernyataan def eksplisit (yaitu bahwa hal itu dapat tertanam dalam ekspresi yang lebih besar)
Menugaskan lambdas untuk nama pada dasarnya hanya menduplikasi fungsi def
- dan secara umum, yang terbaik adalah melakukan sesuatu dengan satu cara untuk menghindari kebingungan dan meningkatkan kejelasan.
Use case yang sah untuk lambda adalah di mana Anda ingin menggunakan suatu fungsi tanpa menugaskannya, misalnya:
sorted(players, key=lambda player: player.rank)
Secara umum, argumen utama yang menentang melakukan ini adalah bahwa def
pernyataan akan menghasilkan lebih banyak baris kode. Tanggapan utama saya untuk itu adalah: ya, dan itu bagus. Kecuali jika Anda bermain golf kode, meminimalkan jumlah garis bukanlah sesuatu yang harus Anda lakukan: lakukan dengan singkat.
def
melalui pemeriksa PEP8, Anda dapatkan E704 multiple statements on one line (def)
, dan jika Anda membaginya menjadi dua baris Anda mendapatkan E301 expected 1 blank line, found 0
: - /
Begini ceritanya, saya punya fungsi lambda sederhana yang saya gunakan dua kali.
a = map(lambda x : x + offset, simple_list)
b = map(lambda x : x + offset, another_simple_list)
Ini hanya untuk representasi, saya telah menghadapi beberapa versi yang berbeda ini.
Sekarang, untuk menjaga keadaan tetap kering, saya mulai menggunakan kembali lambda umum ini.
f = lambda x : x + offset
a = map(f, simple_list)
b = map(f, another_simple_list)
Pada titik ini pemeriksa kualitas kode saya mengeluh tentang lambda menjadi fungsi bernama jadi saya mengubahnya menjadi fungsi.
def f(x):
return x + offset
a = map(f, simple_list)
b = map(f, another_simple_list)
Sekarang pemeriksa mengeluh bahwa suatu fungsi harus dibatasi oleh satu baris kosong sebelum dan sesudah.
def f(x):
return x + offset
a = map(f, simple_list)
b = map(f, another_simple_list)
Di sini kita sekarang memiliki 6 baris kode bukannya 2 baris asli tanpa peningkatan keterbacaan dan tidak ada peningkatan menjadi pythonic. Pada titik ini pemeriksa kode mengeluh tentang fungsi tidak memiliki dokumen.
Menurut pendapat saya aturan ini sebaiknya dihindari dan dilanggar ketika masuk akal, gunakan penilaian Anda.
a = [x + offset for x in simple_list]
. Tidak perlu digunakan map
dan di lambda
sini.
x + offset
bagian ke lokasi abstrak yang dapat diperbarui tanpa mengubah lebih dari satu baris kode. Dengan pemahaman daftar seperti yang Anda sebutkan, Anda masih membutuhkan dua baris kode yang berisi kode-kode itu yang x + offset
sekarang berada dalam daftar pemahaman. Untuk menariknya keluar seperti yang diinginkan penulis, Anda memerlukan a def
atau lambda
.
def
dan lambda
seseorang juga bisa menggunakan functools.partial : f = partial(operator.add, offset)
dan kemudian a = list(map(f, simple_list))
.
def f(x): return x + offset
(yaitu, fungsi sederhana yang didefinisikan pada satu baris)? Setidaknya dengan flake8 saya tidak mendapatkan keluhan tentang baris kosong.
a, b = [[x + offset for x lst] for lst in (simple_list, another_simple_list)]
Lattyware benar sekali: Pada dasarnya PEP-8 ingin Anda menghindari hal-hal seperti
f = lambda x: 2 * x
dan sebaliknya gunakan
def f(x):
return 2 * x
Namun, sebagaimana dialamatkan dalam laporan bug terbaru (Agustus 2014), pernyataan seperti berikut ini sekarang sesuai:
a.f = lambda x: 2 * x
a["f"] = lambda x: 2 * x
Karena pemeriksa PEP-8 saya belum mengimplementasikan ini dengan benar, saya mematikan E731 untuk saat ini.
def
, penguji PEP8 mengeluh E301 expected 1 blank line, found 0
, jadi Anda kemudian harus menambahkan baris kosong yang jelek sebelum itu.
Saya juga menghadapi situasi di mana bahkan tidak mungkin untuk menggunakan fungsi def (ined).
class SomeClass(object):
# pep-8 does not allow this
f = lambda x: x + 1 # NOQA
def not_reachable(self, x):
return x + 1
@staticmethod
def also_not_reachable(x):
return x + 1
@classmethod
def also_not_reachable(cls, x):
return x + 1
some_mapping = {
'object1': {'name': "Object 1", 'func': f},
'object2': {'name': "Object 2", 'func': some_other_func},
}
Dalam hal ini, saya benar-benar ingin membuat pemetaan milik kelas. Beberapa objek dalam pemetaan membutuhkan fungsi yang sama. Adalah tidak masuk akal untuk menempatkan fungsi bernama di luar kelas. Saya belum menemukan cara untuk merujuk ke metode (staticmethod, classmethod atau normal) dari dalam tubuh kelas. SomeClass belum ada saat kode dijalankan. Jadi merujuknya dari kelas juga tidak mungkin.
also_not_reachable
pada definisi pemetaan sebagaiSomeClass.also_not_reachable
f
di 2,7 dan 3,5 bagi saya
@staticmethod
dan @classmethod
tidak membutuhkan objek, hanya SomeClass.also_not_reachable
(meskipun mereka membutuhkan nama yang berbeda). Jika Anda perlu mengaksesnya dari metode kelas, gunakan sajaself.also_not_reachable
*not_reachable
metode Anda sebagai not_as_easily_reachable_from_class_definition_as_a_lambda
xD
flake8
( flake8.pycqa.org )