Apa cara yang tepat untuk digunakan **kwargs
dalam Python ketika datang ke nilai default?
kwargs
mengembalikan kamus, tetapi apa cara terbaik untuk menetapkan nilai default, atau ada satu? Haruskah saya mengaksesnya sebagai kamus? Gunakan fungsi get?
class ExampleClass:
def __init__(self, **kwargs):
self.val = kwargs['val']
self.val2 = kwargs.get('val2')
Sebuah pertanyaan sederhana, tetapi satu yang saya tidak dapat menemukan sumber daya yang baik. Orang melakukannya dengan cara berbeda dalam kode yang saya lihat dan sulit untuk mengetahui apa yang harus digunakan.
__init__()
. Adakah yang bisa menjelaskan mengapa ini pelanggaran yang tidak patut?self.__dict__update(**kwargs)
dapat mendefinisikan kembali metode dan menyebabkan bug lainSementara sebagian besar jawaban mengatakan bahwa, misalnya,
sama dengan"
ini tidak benar. Dalam kasus terakhir,
f
bisa disebut sebagaif(23, 42)
, sementara kasus yang pertama menerima suatu argumen bernama hanya - tidak ada panggilan posisional. Seringkali Anda ingin memberikan fleksibilitas maksimum kepada penelepon dan karena itu bentuk kedua, seperti yang dinyatakan sebagian besar jawaban, lebih disukai: tetapi itu tidak selalu terjadi. Ketika Anda menerima banyak parameter opsional yang biasanya hanya sedikit yang dilewati, mungkin ide yang bagus (menghindari kecelakaan dan kode yang tidak dapat dibaca di situs panggilan Anda!) Untuk memaksa penggunaan argumen yang disebutkan -threading.Thread
adalah contohnya. Bentuk pertama adalah bagaimana Anda menerapkannya di Python 2.Ungkapan ini sangat penting sehingga dalam Python 3 sekarang memiliki sintaks pendukung khusus: setiap argumen setelah satu
*
didef
tanda tangan adalah kata kunci saja, yaitu, tidak dapat dilewatkan sebagai argumen posisi, tetapi hanya sebagai yang bernama. Jadi dalam Python 3 Anda bisa kode di atas sebagai:Memang, dalam Python 3 Anda bahkan dapat memiliki argumen hanya kata kunci yang bukan opsional (yang tanpa nilai default).
Namun, Python 2 masih memiliki tahun-tahun panjang kehidupan produktif di masa depan, jadi lebih baik untuk tidak melupakan teknik dan idiom yang memungkinkan Anda menerapkan dalam Python 2 ide-ide desain penting yang secara langsung didukung dalam bahasa di Python 3!
sumber
Saya menyarankan sesuatu seperti ini
Dan kemudian gunakan nilai apa pun yang Anda inginkan
dictionaryA.update(dictionaryB)
menambahkan kontendictionaryB
untukdictionaryA
menimpa kunci duplikat.sumber
for key in options: self.__setattr__(key, options[key])
dan saya siap berangkat. :)Anda akan melakukannya
atau
Jika Anda menggunakan
pop
, maka Anda dapat memeriksa apakah ada nilai palsu yang dikirim, dan mengambil tindakan yang sesuai (jika ada).sumber
.pop
akan membantu Anda “memeriksa apakah ada nilai palsu yang dikirim”?kwargs
karena suatu alasan.default_value
lulus? Dan menghapus kunci itu sesudahnya?Menggunakan ** kwargs dan nilai default mudah. Kadang-kadang, bagaimanapun, Anda seharusnya tidak menggunakan ** kwargs di tempat pertama.
Dalam hal ini, kami tidak benar-benar memanfaatkan ** kwargs.
Di atas adalah "mengapa repot-repot?" pernyataan. Itu sama dengan
Ketika Anda menggunakan ** kwargs, Anda berarti bahwa kata kunci tidak hanya opsional, tetapi juga kondisional. Ada aturan yang lebih kompleks daripada nilai standar sederhana.
Ketika Anda menggunakan ** kwargs, Anda biasanya memiliki makna lebih seperti yang berikut, di mana standar sederhana tidak berlaku.
sumber
Karena
**kwargs
digunakan ketika jumlah argumen tidak diketahui, mengapa tidak melakukan ini?sumber
Inilah pendekatan lain:
sumber
get_form_kwargs()
.). ccbv.co.uk/projects/Django/1.5/django.views.generic.edit/…get_form()
metode menunjukkan cara mendapatkan argumen kata kunci secara ekstensif dengan menunda ke metode lain (get_form_kwargs
seperti yang disebutkan di atas). Ini instantiates bentuk sebagai berikut:form_class(**self.get_form_kwargs())
.get_form_kwargs()
dalam tampilan subkelas dan menambah / menghapus kwarg berdasarkan logika tertentu. Tapi itu untuk tutorial Django.Saya pikir cara yang tepat untuk digunakan
**kwargs
dalam Python ketika datang ke nilai default adalah dengan menggunakan metode kamussetdefault
, seperti yang diberikan di bawah ini:Dengan cara ini, jika pengguna memasukkan 'val' atau 'val2' pada kata kunci
args
, mereka akan digunakan; jika tidak, nilai default yang telah ditetapkan akan digunakan.sumber
Anda bisa melakukan sesuatu seperti ini
sumber
Menindaklanjuti saran @srhegde untuk menggunakan setattr :
Varian ini berguna ketika kelas diharapkan memiliki semua item dalam
acceptable
daftar kami .sumber
Jika Anda ingin menggabungkan ini dengan * args Anda harus menyimpan * args dan ** kwargs di akhir definisi.
Begitu:
sumber
@AbhinavGupta dan @Steef menyarankan untuk menggunakan
update()
, yang menurut saya sangat membantu untuk memproses daftar argumen besar:Bagaimana jika kita ingin memeriksa bahwa pengguna belum memberikan argumen palsu / tidak didukung? @VinaySajip menunjukkan bahwa
pop()
dapat digunakan untuk memproses daftar argumen secara iteratif. Kemudian, setiap argumen sisa palsu. Bagus.Berikut cara lain yang memungkinkan untuk melakukan ini, yang membuat sintaks sederhana penggunaan
update()
:unknown_args
adalah yangset
berisi nama-nama argumen yang tidak terjadi di default.sumber
Solusi sederhana lain untuk memproses argumen yang tidak dikenal atau banyak dapat:
sumber
** kwargs memberikan kebebasan untuk menambahkan sejumlah argumen kata kunci. Seseorang mungkin memiliki daftar kunci yang dapat digunakan untuk menetapkan nilai default. Tetapi pengaturan nilai default untuk jumlah kunci yang tidak terbatas tampaknya tidak perlu. Akhirnya, mungkin penting untuk memiliki kunci sebagai atribut instance. Jadi, saya akan melakukan ini sebagai berikut:
sumber