Saya sepenuhnya menyadari hal itu pylint
dan alat analisis statis lainnya tidak semuanya tahu, dan kadang-kadang saran mereka harus tidak taat. (Ini berlaku untuk berbagai kelas pesan, bukan hanya convention
s.)
Jika saya punya kelas suka
class related_methods():
def a_method(self):
self.stack.function(self.my_var)
class more_methods():
def b_method(self):
self.otherfunc()
class implement_methods(related_methods, more_methods):
def __init__(self):
self.stack = some()
self.my_var = other()
def otherfunc(self):
self.a_method()
Jelas, itu dibuat-buat. Ini contoh yang lebih baik, jika Anda suka .
Saya percaya gaya ini disebut menggunakan "mixins".
Seperti alat-alat lain, pylint
tingkat kode ini di -21.67 / 10
, terutama karena berpikir more_methods
dan related_methods
tidak memiliki self
atau atribut otherfunc
, stack
, annd my_var
karena tanpa menjalankan kode, itu tampaknya tidak bisa melihat related_methods
dan more_methods
dicampur-in ke implement_methods
.
Kompiler dan alat analisis statis tidak selalu dapat menyelesaikan Masalah Pemutusan , tetapi saya merasa ini jelas merupakan kasus di mana melihat apa yang diwarisi oleh implement_methods
akan menunjukkan ini benar-benar valid, dan itu akan menjadi hal yang sangat mudah untuk dilakukan.
Mengapa alat analisis statis menolak pola OOP yang valid ini (menurut saya)?
Antara:
Mereka bahkan tidak mencoba memeriksa warisan atau
mixin tidak disarankan menggunakan Python idiomatis dan mudah dibaca
# 1 jelas salah karena jika saya meminta pylint
untuk memberi tahu saya tentang kelas saya yang mewarisi unittest.TestCase
yang menggunakan self.assertEqual
, (sesuatu yang didefinisikan hanya dalam unittest.TestCase
), itu tidak mengeluh.
Apakah mixin unpythonic atau berkecil hati?
Jawaban:
Mixin bukan kasus penggunaan yang dianggap oleh alat. Itu tidak berarti itu kasus penggunaan yang buruk, hanya yang tidak umum untuk python.
Apakah mixin digunakan secara tepat dalam contoh tertentu adalah masalah lain. Anti-pola mixin yang paling sering saya lihat adalah menggunakan mixin ketika hanya ada satu kombinasi yang dimaksudkan. Itu hanya jalan memutar untuk menyembunyikan kelas dewa. Jika Anda tidak dapat memikirkan alasan saat ini untuk menukar atau mengabaikan salah satu mixin, itu seharusnya bukan mixin.
sumber
Saya percaya bahwa Mixin dapat, tentu saja, Pythonic. Namun, cara idiomatis untuk membungkam virus Anda - dan meningkatkan keterbacaan Mixins Anda - adalah untuk keduanya (1) mendefinisikan metode abstrak yang secara eksplisit menentukan metode yang harus diterapkan oleh anak-anak Mixin, dan (2) pra-definisi
None
bidang-nilai untuk anggota data Mixin bahwa anak-anak harus menginisialisasi.Menerapkan pola ini pada contoh Anda:
sumber
abstract other(self): pass
itu memperdagangkan kebingungan orang lain untuk sayaSaya pikir mixin bisa baik, tetapi saya juga berpikir pylint benar dalam hal ini. Penafian: hal-hal berdasarkan opini berikut.
Kelas yang baik, termasuk mixin, memiliki satu tanggung jawab yang jelas. Idealnya, mixin harus membawa semua status yang akan diakses, dan logika untuk menanganinya. Misalnya mixin yang baik dapat menambahkan
last_updated
bidang ke kelas model ORM, memberikan logika untuk pengaturannya, dan metode untuk mencari catatan tertua / terbaru.Mengacu pada anggota instance yang tidak dideklarasikan (variabel dan metode) memang terlihat sedikit aneh.
Pendekatan yang tepat sangat tergantung pada tugas yang dihadapi.
Ini mungkin mixin dengan bit relevan dari negara yang disimpan di dalamnya.
Ini mungkin hierarki kelas yang berbeda di mana metode yang saat ini Anda distribusikan melalui mixin berada di kelas dasar, sementara perbedaan implementasi tingkat yang lebih rendah milik subkelas. Ini terlihat paling cocok untuk kasus Anda dengan operasi stack.
Ini mungkin dekorator kelas yang menambahkan satu atau dua metode; ini biasanya masuk akal ketika Anda harus memberikan beberapa argumen kepada dekorator untuk memengaruhi pembuatan metode.
Nyatakan masalah Anda, jelaskan masalah desain Anda yang lebih besar, maka kami dapat berdebat jika ada sesuatu yang anti-pola dalam kasus Anda.
sumber
Linter tidak sadar bahwa Anda menggunakan kelas sebagai mixin. Pylint sadar bahwa Anda menggunakan mixin jika Anda menambahkan akhiran 'mixin' atau 'Mixin' di akhir nama kelas, maka linter berhenti mengeluh.
Mixin tidak buruk atau bagus, hanya alat. Anda menjadikannya sebagai penggunaan yang baik atau penggunaan yang buruk.
sumber
Apakah mixin oke?
Mixin tidak disarankan - mereka adalah use-case yang bagus untuk multiple inheritance.
Mengapa linter Anda mengeluh?
Pylint jelas mengeluh karena tidak tahu di mana
otherfunc
,stack
danmy_var
berasal.Sepele?
Tidak ada alasan langsung yang jelas bagi Anda untuk memisahkan kedua metode ini ke dalam kelas induk yang terpisah, baik dalam contoh Anda dalam pertanyaan, atau dalam contoh terkait Anda yang lebih sepele, yang ditunjukkan di sini.
Biaya mixin dan kebisingan
Biaya dari apa yang Anda lakukan adalah membuat laporan laporan Anda berisik. Kebisingan itu dapat mengaburkan masalah yang lebih penting dengan kode Anda. Ini adalah biaya penting untuk menimbang. Biaya lain adalah bahwa Anda memisahkan kode yang saling terkait menjadi ruang nama yang berbeda yang dapat mempersulit programmer untuk menemukan artinya.
Kesimpulan
Warisan memungkinkan penggunaan kembali kode. Jika Anda mendapatkan kode yang dapat digunakan kembali dengan mixin Anda, hebat, mereka telah menciptakan nilai untuk Anda yang mungkin lebih besar daripada kemungkinan biaya lainnya. Jika Anda tidak mendapatkan penggunaan kembali / deduplikasi baris kode, Anda mungkin tidak mendapatkan banyak nilai untuk mixin Anda, dan pada saat itu, saya pikir biaya kebisingan lebih besar daripada manfaatnya.
sumber