Apakah ada gaya pengkodean yang direkomendasikan / diterima secara umum untuk menangani situasi di mana suatu fungsi mengembalikan tupel nilai tetapi hanya satu dari nilai-nilai itu yang digunakan sesudahnya (perhatikan bahwa ini sebagian besar dimaksudkan untuk fungsi pustaka yang tidak dapat saya ubah - menulis pembungkus di sekitar panggilannya mungkin sedikit berlebihan ...)? Alih-alih melakukan
a, b, c = foo()
dan kemudian tidak menggunakan b
dan c
, mana dari varian berikut harus lebih disukai (atau ada yang lain?):
Varian 1 (garis bawah)
a, _, _ = foo()
(yang sangat jelas dan sederhana tetapi mungkin berbenturan dengan yang _ = gettext.gettext
digunakan dalam banyak aplikasi yang menggunakan terjemahan)
Varian 2 (nama dummy)
a, unused, unused = foo()
(Tidak terlalu menarik, saya pikir, hal yang sama berlaku untuk nama lain seperti dummy
)
Varian 3 (indeks)
a = foo()[0]
(Bagiku ()[0]
tampilannya tidak pythonic ...)
sumber
a, b = foo()[0:2]
akan berhasil? Jika ya: ya, ya :)a, *_ = foo()
akan membuang semua nilai kecuali yang pertama.Jawaban:
Menggunakan garis bawah untuk variabel yang tidak digunakan pasti dapat diterima. Berhati-hatilah, dalam beberapa basis kode itu bukan pilihan karena pengenal itu dicadangkan sebagai singkatan
gettext
. Ini adalah keberatan paling sering terhadap gaya ini (meskipun ini bukan masalah bagi mayoritas sejauh yang saya bisa menilai). Saya masih merekomendasikannya, dan selalu menggunakannya sendiri.Nama suka
dummy
atauunused
cenderung membuat saya jengkel secara pribadi, dan saya tidak sering melihatnya (dengan Python, yaitu - Saya tahu basis kode Delphi yang menggunakandummy
secara bebas, dan ia juga bocor ke skrip yang terkait dengan program yang dimaksud). Saya akan menyarankan Anda menentangnya.Hanya mengekstraksi satu item dari tuple yang dikembalikan juga tidak masalah. Ini juga menghemat beberapa kerumitan dengan mendapatkan jumlah nilai yang tidak digunakan dengan benar. Perhatikan bahwa ada dua kelemahan potensial:
sumber
Pylint membuat saya terbiasa melakukannya dengan cara ini:
Artinya, hasil yang tidak digunakan memiliki nama deskriptif diawali oleh _. Pylint menganggap penduduk lokal yang diawali dengan _ sebagai tidak terpakai, dan global atau atribut diawali dengan _ sebagai pribadi.
sumber
Jika di seluruh proyek Anda, Anda hanya melakukan ini sekali atau sangat jarang menggunakan fungsi tertentu, saya akan menggunakan Varian 1 jika Anda tahu
gettext
bukan masalah dalam modul itu, dan sebaliknya Varian 3.Di sisi lain, jika Anda melakukan ini banyak - dan terutama jika setiap kali Anda ingin yang berbeda subset dari nilai kembali (membuat wrapper untuk hanya mengembalikan orang-orang yang Anda sayangi unviable), mungkin akan bermanfaat untuk menulis pembungkus yang menempatkan hasilnya ke dalam tuple bernama , atau turunan dari beberapa kelas deskriptif lain, yang memungkinkan Anda melakukannya:
Dan kemudian bekerja dengan
bar.a
,bar.b
danbar.c
.sumber
Seperti yang orang lain katakan, garis bawah (
_
) adalah standar. Tetapi jika garis bawah digunakan untuk terjemahan, saya pikir garis bawah ganda adalah alternatif terbaik.var, __, value = "VAR=value".partition('=')
Lebih baik dari ini:
var, unused, value = "VAR=value".partition('=')
var, unused_del, value = "VAR=value".partition('=')
var, _del, value = "VAR=value".partition('=')
sumber
Saya seorang programmer non-Python, tetapi bagi saya varian ketiga paling masuk akal.
Dalam varian 3 Anda benar-benar jelas nilai mana yang Anda minati. Dalam varian 1 dan 2, Anda menetapkan nilai kembali ke variabel, dan dengan demikian, mereka dapat digunakan. Anda mungkin menamainya dengan tidak jelas, tetapi penamaan yang buruk sebenarnya bukan solusi untuk masalah apa pun.
Selain kejelasan, mengapa Anda ingin menetapkan nilai yang tidak digunakan ke slot di memori (seperti dalam varian 1 dan 2)? Ini akan menjadi solusi yang buruk dalam hal manajemen memori.
sumber
Berikut aturan umum: Jika hanya 1 dari nilai yang dikembalikan digunakan, mengapa tidak mengembalikan saja 1 nilai itu? Jika flag dipanggil dari beberapa tempat, simpan flag untuk nilai yang sama dan kembalikan sesuai dengan flag.
EDIT:
Jika saya berada dalam situasi Anda, dan saya belum menulis fungsinya, saya mungkin akan memilih Variant 2. Saya akan menyimpan nama-nama boneka di sana sehingga parameter dapat digunakan jika perlu. Mengiris daftar akan memiliki sedikit overhead. Mungkin Anda dapat menyisihkan beberapa byte untuk menerima data yang tidak diinginkan.
sumber
%timeit a, _, _ = foo()
vs%timeit a = foo()[0]
yang menghasilkan 123ns vs 109ns, yaitu pengirisan tampaknya sebenarnya lebih cepat daripada nilai membongkar. Atau apakah Anda memiliki situasi tertentu dalam pikiran?