Sebagai contoh mari kita asumsikan saya ingin subclass dict
dan memiliki semua kunci dikapitalisasi:
class capdict(dict):
def __init__(self,*args,**kwds):
super().__init__(*args,**kwds)
mod = [(k.capitalize(),v) for k,v in super().items()]
super().clear()
super().update(mod)
def __getitem__(self,key):
return super().__getitem__(key.capitalize())
def __setitem__(self,key,value):
super().__setitem__(key.capitalize(),value)
def __delitem__(self,key):
super().__detitem__(key.capitalize())
Ini berfungsi sampai batas tertentu,
>>> ex = capdict(map(reversed,enumerate("abc")))
>>> ex
{'A': 0, 'B': 1, 'C': 2}
>>> ex['a']
0
tetapi, tentu saja, hanya untuk metode yang saya ingat untuk diterapkan, misalnya
>>> 'a' in ex
False
bukan perilaku yang diinginkan.
Sekarang, cara malas mengisi semua metode yang dapat diturunkan dari yang "inti" akan bercampur collections.abc.MutableMapping
. Hanya saja, itu tidak berfungsi di sini. Saya kira karena metode yang dimaksud ( __contains__
dalam contoh) sudah disediakan oleh dict
.
Apakah ada cara mendapatkan kue dan memakannya? Beberapa sihir membiarkan MutableMapping
hanya melihat metode yang telah saya timpa sehingga itu meningkatkan yang lain berdasarkan itu?
python
python-3.x
Paul Panzer
sumber
sumber
MutableMapping
. Lihat kamus case-sensitive .os._Environ
.Jawaban:
Apa yang dapat Anda lakukan:
Hal ini kemungkinan besar tidak akan bekerja dengan baik (yaitu tidak desain terbersih), tapi Anda bisa mewarisi dari MutableMapping pertama dan kemudian dari dict kedua.
Maka MutableMapping akan menggunakan metode apa pun yang telah Anda terapkan (karena mereka adalah yang pertama dalam rantai pencarian):
Cara yang lebih baik:
Pendekatan terbersih (mudah dipahami dan diuji) adalah dengan hanya mewarisi dari MutableMapping dan kemudian menerapkan metode yang diperlukan menggunakan dict biasa sebagai penyimpanan data dasar (dengan komposisi daripada pewarisan):
sumber
super
s untukdict
s eksplisit maka tampaknya berfungsi, kecualilen
pengembalian0
. Dari mana datangnya?(D, MutableMapping, dict)
. Itu adalah metode MutableMappiing .__ len __ () yang selalu mengembalikan 0. Itu tidak dimaksudkan untuk dipanggil secara langsung - itu selalu seharusnya diganti. Itu sebabnya Anda harus menelepondict.__len__(self)
langsung. Dan itulah salah satu alasan mengapa saya mengatakan "ini kemungkinan tidak akan berhasil" ;-)