Kisah Holivarny tentang linter

Kita semua menulis kode. Banyak kode. Tentu saja ada kesalahan. Terkadang itu hanya kode yang bengkok, dan terkadang harga kesalahan adalah pesawat ruang angkasa yang meledak. Tentu saja, tidak ada yang membuat tiang tembok yang disengaja, semua orang mencoba memantau kualitas dengan kemampuan terbaik mereka, tetapi tanpa alat analisis statis, hampir tidak mungkin untuk memastikan bahwa semuanya sempurna.

Linter membantu membawa kode ke gaya tunggal dan menghindari kesalahan. Benar, hanya jika Anda siap menderita, dan jangan mengabaikan pada akhirnya "pylint: disable", hanya untuk membuatnya tertinggal. Apa yang seharusnya menjadi linter, dan mengapa Pylint tidak bisa melakukannya, tahu Nikita Sobolevn , yang sangat mengerti dan sangat mencintai linter sehingga ia bahkan menamai perusahaannya sehingga tidak membuat mereka kesal - wemake.services.

gambar

Di bawah ini adalah versi teks laporan pada Moscow Python Conf ++ tentang linters, cara melakukannya dengan benar dan bagaimana tidak. Presentasi memiliki banyak interaktivitas, online dan komunikasi dengan audiens. Pembicara, sepanjang jalan, melakukan jajak pendapat dan mencoba meyakinkan penonton: dia melihat tren, dan seperti dalam debat, dia mencoba untuk menyamakan rasio dan mengubah opini publik. Beberapa bagian dari jajak pendapat jatuh ke dalam dekripsi, tetapi tidak semua, sehingga video dilampirkan untuk melengkapi gambar.



Mengapa kita membutuhkan linter?


Tugas terpenting linter adalah membawa kode ke keseragaman . Ada banyak opsi untuk menulis hal yang sama dengan Python: beri koma di sini atau di sana, lupa untuk menutup kurung, atau jangan lupa. Ketika orang menulis kode untuk waktu yang lama, itu menjadi seperti tambal sulam potongan yang berbeda dijahit pada waktu yang berbeda. Sangat tidak menyenangkan untuk bekerja dengan selimut seperti itu, ia tidak suka membaca kode, yang sangat buruk.

Linter membuat hidup lebih mudah saat ditinjau . Saya datang ke ulasan kode dan berpikir: β€œSaya tidak ingin melakukan ini! Sekarang akan ada ruang ekstra dan omong kosong lainnya! " Saya ingin orang lain menyiapkan kode yang baik, dan setelah itu saya akan menghargai hal-hal konseptual yang hebat.

Terkadang saya melihat kode dan berpikir bahwa semuanya baik-baik saja, dan kemudian saya melihat dalam beberapa fungsi terlalu banyak variabel atau kesalahan yang tidak saya perhatikan. Otomatis akan menemukan kesalahan ini, tetapi saya melihat. Agar tidak jatuh ke dalam situasi seperti itu - saya menggunakan linter - dia menemukan segala sesuatu yang tersembunyi dan sulit ditemukan.

Apa itu linter?


Yang paling sederhana hanya memeriksa gaya , misalnya, Flake8 . Dalam batas tertentu, juga Black, tetapi lebih merupakan autoformer-linter. Linters menguji semantik lebih sulit , dan bukan hanya gaya: apa yang Anda lakukan, mengapa, dan mengalahkan Anda di tangan jika Anda menulis dengan kesalahan. Contoh yang baik adalah Pylint , yang kita semua tahu, gunakan dan cintai. Saya menyebut linter ini - Praktik terbaik . Tipe ketiga adalah Tipe checking , linter ini sedikit ke samping. Pengecekan tipe dalam Python adalah hal baru, sekarang dibuat oleh dua platform yang bersaing: Mypy dan Pyre .

Bagaimana cara menggunakan linter?


Saya tidak mengklaim bahwa linter adalah obat mujarab dan pengganti segalanya. Ini tidak benar. Linter - langkah pertama piramida, di mana kode masuk ke produksi.

Ada tiga langkah di piramida:

  • Luncurkan linter . Ini sangat cepat dan tidak memerlukan apa pun kecuali kode sumber - tidak ada infrastruktur, tidak ada pengaturan. Periksa: cek kewarasan pertama berlalu - semuanya baik-baik saja, kami sedang mengerjakan.
  • Tahap uji coba . Proses ini lebih rumit dan lebih lama karena kesalahan bukan kode. Kita akan memerlukan pengaturan yang benar dan lengkap dari seluruh aplikasi.
  • Ulasan panggung .



Ini adalah langkah - langkah yang diperlukan agar kode dapat mulai diproduksi. Jika Anda tidak melalui satu langkah, lupa sesuatu, atau pengulas mengatakan itu tidak akan berhasil, Anda akan melihat tulisan: gagal - kode yang buruk tidak masuk ke dalam produksi.

Apakah Anda menggunakan linter di tempat kerja?


Jika Anda bertanya kepada pengembang dari perusahaan yang keras, di mana mereka bekerja 7 hari seminggu, apakah mereka menggunakan linter, maka ternyata setidaknya sepertiga dari mereka menggunakan linter dengan sangat ketat: tetes CI, cek sangat berat . Sisanya kira-kira sama-sama menerapkan linter hanya untuk memeriksa gaya , tidak pernah sebagai sistem pelaporan : mereka memulai linter, menghasilkan laporan dan melihat seberapa buruk semuanya. Linter digunakan, dan itu bagus. Di perusahaan kami, semuanya dibangun dengan sangat keras: tautan keras, banyak cek, tinjauan kode ganda.

Ulasan kode


Masalah muncul hanya pada tahap ini. Ini adalah langkah paling atas dan paling sulit dari piramida: tinjauan kode tidak dapat diotomatisasi, dan jika mungkin, ini akan mengarah pada otomatisasi penulisan kode. Maka programmer tidak akan dibutuhkan.

Secara default, prosesnya terlihat seperti ini: kode masuk untuk ditinjau, saya menemukan kesalahan, dan saya tidak ingin membuatnya lagi. Sebagai contoh, saya melihat bahwa pengembang menangkap BaseException: β€œJangan lakukan itu. Tolong jangan tangkap! " Setelah 10 hari, hal yang sama. Saya mengingatkan Anda lagi:

- Kami tidak menangkap BaseException.
" Bagus, aku mengerti."

Setahun berlalu - kesalahan yang sama. Seorang pria baru datang - kesalahan yang sama. Saya pikir - bagaimana kita mengotomatiskan semuanya sehingga situasinya tidak terjadi lagi, dan hanya terlintas dalam pikiran: β€œ Mari kita hancurkan orang-orang kita? Β»Mari kita buat paket terbuka, letakkan semua aturan yang kita gunakan di tempat kerja dan otomatisasi pemeriksaan aturan sehingga setiap kali kita tidak menulis dengan tangan. Kami mengotomatiskan semuanya dengan baik dan segera!

Secara alami, Anda dapat mengatakan: " Linter siap pakai sudah ada, mereka bekerja, semua orang menggunakannya - mengapa melakukannya sendiri?", Dan Anda akan benar, karena memang ada linter. Mari kita lihat mana dan apa yang mereka lakukan.

Pylint


Pada tajuk " Mengapa tidak Pylint?" "Saya sudah sering mendengar pertanyaan ini. Saya akan menjawabnya dengan lebih lembut. Pylint adalah alat bintang rock yang hebat untuk kode Python, tetapi ia memiliki fitur yang tidak ingin saya lihat di linter saya.

Ini menggabungkan semuanya: pemeriksaan gaya, Praktik terbaik, dan Pengecekan tipe . Pemeriksaan jenis Pylint kurang berkembang karena tidak ada informasi jenis: ia mencoba menampilkannya entah bagaimana, tetapi tidak berhasil dengan baik. Oleh karena itu, sering ketika saya menulis model_name.some_property di Django, saya dapat melihat kesalahan: "Maaf, tidak ada properti seperti itu - Anda tidak dapat menggunakannya!" Saya ingat bahwa ada sebuah plugin, saya menginstalnya, kemudian saya menggunakan Seledri, itu juga memulai beberapa jenis masalah, saya menginstal plugin untuk Seledri, menggunakan beberapa perpustakaan ajaib lainnya, dan sebagai hasilnya, saya hanya menulis di mana-mana: "pylint: disable" ... Bukan begitu apa yang ingin saya dapatkan dari linter.

Fitur lain yang tersembunyi dari pengguna adalah bahwa Pylint memiliki implementasi sendiri pohon sintaksis abstrak di Python . Ini adalah bagaimana kode terlihat ketika Anda menguraikannya dan mendapatkan informasi tentang pohon node yang membentuk kode. Saya tidak terlalu mempercayai implementasi saya sendiri, karena selalu salah.

Selain Pylint, ada linter lain yang juga melakukan pekerjaan mereka.

Sonarquube


Alat luar biasa, tetapi terpisah yang hidup di suatu tempat dekat dengan proyek Anda.

  • SonarQube tidak akan dapat berjalan sering : perlu dikerahkan di suatu tempat, menonton, memantau, mengkonfigurasi.
  • Itu ditulis dalam Java . Jika Anda ingin memperbaiki linter untuk Python, Anda akan menulis kode dalam Java. Saya pikir secara konsep ini salah - pengembang yang dapat menulis dengan Python harus dapat menulis kode untuk menguji Python.

Perusahaan yang mengembangkan SonarQube secara khusus melihat konsep pengembangan produk. Ini bisa jadi masalah.

Keuntungan dari SonarQube adalah ia memiliki pemeriksaan yang sangat keren yang menunjukkan kompleksitas, kemungkinan kesalahan tersembunyi dan bug. Saya suka cek, saya akan meninggalkan mereka, dan mengubah platform.

Serpihan8


Linter yang indah sangat sederhana, tetapi dengan satu masalah: ada beberapa aturan yang digunakan untuk memeriksa seberapa baik kodenya ditulis. Pada saat yang sama, Flake8 memiliki banyak plugin yang sangat sederhana: plugin minimum adalah 2 metode yang perlu diimplementasikan. Saya pikir - mari kita ambil Flake8 sebagai dasar dan menulis plugin, tetapi dengan pemahaman kita tentang manfaatnya bagi perusahaan. Dan begitulah yang kami lakukan.

Lapisan yang paling ketat di dunia


Kami membuat alat di mana kami mengumpulkan segala sesuatu yang kami pikir tepat untuk Python dan disebut wemake-python-styleguide . Plugin ini diposting secara publik, karena saya percaya bahwa Open Source by Default adalah praktik yang baik . Saya sangat yakin bahwa banyak alat akan mendapat manfaat jika diunggah ke Open Source. Untuk instrumen kami, kami datang dengan slogan: "Lapisan yang paling ketat di dunia!"

Kata kunci dalam kata-kata kita adalah ketat, yang berarti rasa sakit dan penderitaan.

Jika Anda menggunakan kain linter, dan itu tidak membuat Anda menderita sehingga Anda memegang kepala Anda: "Mengapa Anda tidak menyukainya, sial," maka ini adalah kain linter yang buruk. Itu melompati kesalahan, tidak cukup memantau kualitas kode, dan kita tidak membutuhkannya. Kami membutuhkan yang paling ketat di dunia, yang banyak memeriksa. Sekarang kami memiliki sekitar 250 tes berbeda di kedua kategori : gaya dan Praktik terbaik, tetapi tanpa pemeriksaan Jenis. Mypy terlibat di dalamnya, kami tidak peduli dengannya.

Linter kami tidak memiliki kompromi . Kami tidak memiliki aturan dari kategori "Saya tidak ingin melakukan ini, tetapi jika Anda benar-benar ingin, maka Anda dapat melakukannya." Tidak, kami selalu berbicara kasar - kami tidak melakukannya, karena itu buruk. Kemudian orang-orang datang dan berkata: "Ada 2,5 use case di mana hal ini dimungkinkan pada prinsipnya!". Jika ada kasus-kasus seperti itu, tulis dengan jelas bahwa baris ini diperbolehkan untuk diabaikan oleh linter, tetapi jelaskan alasannya. Itu harus berupa komentar tentang mengapa Anda mengizinkan beberapa praktik aneh dan mengapa Anda melakukannya. Pendekatan ini juga berguna untuk mendokumentasikan kode.

Lapisan yang paling ketat tidak memerlukan pengaturan (WIP) . Kami masih memiliki pengaturan, tetapi kami ingin menyingkirkannya: memiliki kebebasan, pengguna pasti akan mengonfigurasi sehingga linter tidak akan berfungsi dengan benar.

Alat yang baik tidak memerlukan pengaturan - ia memiliki nilai default yang baik.

Dengan pendekatan ini, kode akan konsisten dan akan bekerja sama untuk semua orang, setidaknya secara teori. Kami masih mengerjakan ini, dan sementara ada pengaturan, Anda dapat menggunakan alat kami dan menyesuaikannya untuk Anda sendiri.

Kepada siapa kita bergantung?


Dari sejumlah besar alat.

  • Serpihan8 .
  • Eradicate adalah plugin keren yang menemukan fragmen komentar dalam kode dan membuat Anda menghapusnya, karena menyimpan kode mati dalam suatu proyek adalah buruk. Kami tidak diizinkan melakukannya.
  • Isort adalah alat yang memaksa Anda untuk mengurutkan impor dengan benar: dalam urutan, indentasi, kutipan indah.
  • Bandit adalah alat yang hebat untuk memeriksa keamanan kode secara statis. Ia menemukan kata sandi kabel, penggunaan kikuk assert dalam kode, panggilan ke Popen , sys.exit dan mengatakan bahwa semua ini tidak dapat digunakan, tetapi jika Anda mau, ia meminta untuk menulis alasannya.
  • Dan lebih dari 20 plugin yang memeriksa tanda kurung, tanda kutip dan koma.

Apa yang kita periksa?


Ada 4 kelompok aturan yang kami gunakan dan tegakkan.

Kompleksitas adalah masalah terbesar. Kami tidak tahu apa itu kompleksitas dan kami tidak melihatnya dalam kode. Kami melihat kode yang kami gunakan setiap hari dan sepertinya itu tidak rumit - ambil, baca, semuanya berfungsi. Ini tidak benar. Kode sederhana adalah kode yang dikenal. Kompleksitas memiliki kriteria yang jelas yang kami uji. Tentang kriteria sendiri - nanti. Jika kode melanggar kriteria, maka kita berkata: "Kode ini rumit, tulis ulang!"

Nama untuk variabel adalah masalah pemrograman yang tidak terselesaikan. Siapa yang akan membaca kapan dan dalam konteks apa tidak jelas. Kami mencoba membuat nama yang konsisten dan dapat dimengerti mungkin, tetapi meskipun kami mencoba, masalahnya belum sepenuhnya terselesaikan.

Untuk konsistensi , kami memiliki aturan sederhana - tulis yang sama di mana-mana. Jika ada pendekatan yang disetujui, gunakan di mana-mana. Tidak masalah apakah Anda suka atau tidak, konsistensi lebih penting.

Kami mencoba menggunakan hanya praktik terbaik. Jika kita tahu bahwa beberapa latihan tidak terlalu baik, maka kita melarang penggunaannya. Jika pengembang ingin menggunakan praktik terlarang, maka kami mengharapkan argumen darinya: mengapa dan mengapa berlaku. Mungkin, selama proses deskripsi, pemahaman akan muncul mengapa itu buruk.

Apa itu kompleksitas?


Kompleksitas memiliki metrik khusus yang dapat Anda lihat dan katakan apakah itu sulit atau tidak. Ada banyak dari mereka.

Kompleksitas Siklomatik - kompleksitas siklomatik favorit semua orang. Ini menemukan dalam kode sejumlah besar bersarang if , for , struktur lain, dan menunjukkan terlalu banyak percabangan kode dan kesulitan dalam membaca. Semuanya buruk dengan kode yang disematkan: Anda membaca, membaca, membaca - kembali, membaca, membaca, membaca - melompat, lalu ke siklus lain. Tidak mungkin melewati kode seperti itu dari atas ke bawah dengan aman.

Argumen, Pernyataan, dan Pengembalian. Ini adalah metrik kuantitatif: berapa banyak argumen dalam fungsi atau dalam metode, berapa banyak yang ada di dalam tubuh fungsi ini atau metode pernyataan dan pengembalian.

Kohesi dan Kopling adalah metrik OOP yang populer. Kohesi menunjukkan keterhubungan kelas di dalamnya. Misalnya, ada kelas, dan di dalam Anda menggunakan semua metode dan properti - semua yang Anda nyatakan. Ini adalah kelas yang bagus dengan konektivitas tinggi di dalamnya. Kopling adalah seberapa banyak berbagai bagian sistem terhubung: modul dan kelas. Kami ingin mencapai konektivitas maksimum di dalam kelas dan konektivitas minimum di luar. Maka sistem ini mudah dipelihara dan berfungsi dengan baik.

Kompleksitas Jones - Saya meminjam metrik ini, tetapi hanya karena itu adalah bom! Kompleksitas Jones menentukan kompleksitas suatu garis - semakin kompleks garis itu, semakin sulit untuk dipahami, karena ingatan manusia jangka pendek tidak dapat memproses lebih dari 5-9 objek sekaligus. Inilah yang disebut dompet Miller .

Kami melihat metrik penting ini dan beberapa lainnya, yang jauh lebih besar, dan menentukan apakah kodenya cocok atau tidak. Dalam pemahaman kami, kompleksitas adalah air terjun .

Kesulitan air terjun


Kesulitan dimulai dengan fakta bahwa kami menulis baris, dan itu masih bagus. Tetapi kemudian bisnis datang dan mengatakan bahwa harga telah berlipat ganda, dan kita kalikan dengan 2. Pada titik ini, Kompleksitas Jones menjadi gila dan mengatakan bahwa sekarang jalurnya terlalu rumit - terlalu banyak logika.

Kita memulai variabel baru, dan penganalisa kompleksitas fungsi mengatakan:

- Tidak, tidak begitu - sekarang ada terlalu banyak variabel di dalam fungsi.

Saya akan membuat metode baru, dan saya akan memberikan argumen untuk itu. Sekarang memeriksa jumlah argumen fungsi, atau jumlah metode di dalam kelas, mengatakan bahwa ini juga tidak mungkin - kelasnya terlalu kompleks dan harus dibagi menjadi dua bagian. Hancur dengan menyorot kelas lain. Sekarang ada lebih banyak kelas dan semuanya baik-baik saja, tetapi memeriksa kompleksitas laporan modul bahwa modul itu sekarang terlalu rumit dan perlu dire-refored. Kenapa?

Ini disebut penderitaan. Itulah sebabnya saya mengatakan bahwa seorang kekasih harus membuat Anda menderita. Kami mulai dengan mengalikan 2 dalam satu baris, dan berakhir dengan refactoring seluruh sistem . Menambahkan sepotong kecil kode mengarah ke refactoring seluruh modul, karena kompleksitas menyebar seperti air terjun, dan mencakup semua yang mungkin.

"Need to refactor" - hal ini membuat Anda memperbaiki kode. Anda tidak bisa hanya duduk: "Saya tidak menyentuh kode ini, sepertinya berhasil." Tidak, suatu hari Anda akan mengubah kode di tempat lain, dan air terjun kompleksitas akan membanjiri modul yang tidak Anda sentuh dan Anda harus memperbaikinya. Saya percaya bahwa refactoring itu baik, dan semakin banyak, semakin stabil dan lebih baik sistem Anda bekerja. Dan yang lainnya subjektif!

Sekarang mari kita bicara tentang selera. Ini adalah bagian yang holistik dan interaktif!

Holivar


Biarkan dukungan, komentar terbuka. Pertama, izinkan saya mengingatkan Anda bahwa nama adalah masalah yang kompleks dan belum terselesaikan. Anda dapat memperdebatkan cara memberi nama variabel, tetapi kami memiliki beberapa pendekatan yang membantu setidaknya untuk tidak membuat kesalahan yang jelas.

Nama


Bagaimana Anda suka: var, nilai, barang, objek, data, hasil ? Apa itu data ? Beberapa data. Apa hasilnya ? Semacam hasil. Seringkali saya melihat variabel hasil dan panggilan ke beberapa metode infernal dalam kelas yang tidak dapat dipahami - dan saya berpikir: β€œApa hasil ini? Kenapa dia ada di sini? "

Ada banyak pengembang yang tidak setuju dengan saya dan mengatakan bahwa nilai adalah nama variabel normal:

- Saya selalu menggunakan kunci dan nilai!
- Mengapa tidak menggunakan kunci dan nilai, tetapi katakan bahwa kuncinya adalah nama dan nilai adalah nama belakang? Mengapa tidak mungkin memberi nama first_name dan last_name - sekarang ada konteksnya.

Biasanya orang setuju, tetapi mereka tetap berdebat. Ini adalah hal yang sangat holistik: setidaknya 3 orang menghabiskan satu jam hidup mereka untuk berdebat dengan saya.

Apakah boleh menyebutkan variabel dengan satu huruf?


Misalnya, q ? Kita semua tahu kasus klasik: for i in some_iterable: Apa aku ? Dalam C, ini adalah praktik standar, dan semuanya berasal darinya. Namun dalam Python, koleksi dan iterator. Koleksi berisi elemen yang memiliki nama - sebut saja mereka entah bagaimana berbeda.

Setengah dari pengembang berpikir bahwa memanggil variabel i, x, y, z adalah normal.

Saya percaya bahwa Anda tidak dapat menyebutkan nama dengan satu huruf. Saya ingin lebih banyak konteks dan ada baiknya bahwa paruh kedua pengembang setuju dengan saya. Jika dalam C ini entah bagaimana masih diizinkan karena warisan sejarah, maka dalam Python ini adalah masalah yang sangat besar dan Anda tidak perlu melakukan itu.

Konsistensi


Mari kita memilih satu jalan keluar dari banyak jalan, dan berkata, "Ayo lakukan." Apakah itu baik atau buruk - itu tidak masalah lagi - hanya konsisten.

Kami hanya berbicara tentang Python 3, Legacy tidak dianggap sama sekali.

Saya punya argumen: ketika kita mewarisi dari sesuatu, kita harus tahu dari apa - alangkah baiknya untuk melihat nama orang tua. Yang lucu adalah bahwa biasanya kita melihat nama induknya, kecuali saat ini adalah obyek . Oleh karena itu, saya merumuskan aturan untuk diri saya sendiri: ketika saya menulis sebuah kelas, saya mewarisi dari sesuatu - saya selalu menulis nama orang tua. Tidak masalah apa yang akan terjadi - Model, objek atau sesuatu yang lain.

Jika ada pilihan untuk menulis Class Some(object) atau class Some , maka saya akan memilih yang pertama. Di satu sisi, itu menunjukkan bahwa kita jelas selalu menulis apa yang kita warisi. Di sisi lain, tidak ada verbositas khusus di dalamnya : kita tidak kehilangan apa-apa dari beberapa penekanan tombol tambahan.

Dua pertiga pengembang lebih terbiasa dengan opsi kedua, dan saya bahkan tahu mengapa. Hipotesis saya: semua karena kami telah lama bermigrasi dari versi kedua Python ke yang ketiga, dan sekarang kami menunjukkan bahwa kami menulis dalam Python ketiga. Saya tidak tahu bagaimana hipotesis itu benar, tetapi menurut saya itu benar.

F-line mengerikan?


Opsi Jawaban:

  • Ya: mereka kehilangan konteks, menaruh logika di template dan tidak serat - (38%).
  • Tidak! Mereka adalah keajaiban! - (62%).

Ada hipotesis bahwa f-line mengerikan. Mereka mendorong apapun ke dalamnya! f-lines tidak sama dengan .format , perbedaannya dramatis. Ketika kami mendeklarasikan templat, dan kemudian memformatnya, kami melakukan dua tindakan secara terpisah: pertama kami mendefinisikan templat, dan kemudian memformatnya. Ketika kami mendeklarasikan f-line, kami melakukan dua tindakan secara bersamaan: kami segera mendeklarasikan template dan memformatnya pada saat yang sama.

Ada dua masalah dengan f-line. Kami menyatakan templat untuk f-line dan semuanya berfungsi. Dan kemudian kami memutuskan untuk memindahkan templat 2 baris ke atas atau memindahkannya ke fungsi lain - dan semuanya rusak. Sekarang tidak ada konteks yang memungkinkan kami untuk memformat string , dan kami tidak dapat memprosesnya dengan benar. Masalah besar kedua dengan f-lines: mereka memungkinkan Anda untuk melakukan hal yang mengerikan - memasukkan logika ke dalam template . Misalkan ada baris di mana kita cukup memasukkan nama pengguna dan kata "Halo" - ini normal. Tidak ada yang sangat mengerikan, tetapi kemudian kita melihat bahwa nama pengguna ditulis dengan huruf kapital, kami memutuskan untuk menerjemahkannya ke dalam Judul kasus dan menulis langsung di templat username.title() . Kemudian, kondisi, siklus, impor muncul di templat. Dan semua bagian lain dari php.

Semua masalah ini membuat saya mengatakan bahwa f-line adalah topik yang buruk , kami tidak menggunakannya. Yang lucu adalah kami tidak memiliki case di mana hanya f-line yang cocok untuk kami. Biasanya setiap pemformatan cocok, tetapi kami memilih .format - yang lainnya tidak mungkin - % , atau f-line. Karya .format juga di-linted, karena di dalamnya Anda dapat menaruh tanda kutip dan menulis nama variabel atau urutannya.

Selama laporan, jumlah lawan f-line meningkat dari 33 menjadi 38% - ini adalah kemenangan kecil, tetapi.

Angka-angka


Apakah Anda suka angka seperti ini: final_score = 69 * previous result / 3.14 . Ini terlihat seperti baris kode standar, tetapi apa itu 69? Pertanyaan seperti itu sering muncul ketika saya melihat kode yang saya tulis beberapa waktu lalu, dan manajer pada saat itu mengatakan:

- Harap kalikan dengan 147.
- Kenapa di 147?
- Kami memiliki tarif seperti itu.

Saya mengalikan dan lupa, atau untuk waktu yang lama saya mengambil beberapa nilai dari koefisien sehingga semuanya bekerja - dan kemudian saya lupa bagaimana saya mengambilnya dan mengapa. Ternyata pekerjaan penelitian penting tetap tersembunyi di balik angka yang tidak berjudul. Saya bahkan tidak tahu apa nomor ini, tetapi saya hanya bisa menemukan, mengingat, dan mengembalikannya entah bagaimana dengan melakukan nanti.

Mengapa tidak melakukannya secara berbeda - masukkan semua bilangan kompleks ke dalam variabel Anda sendiri dengan nama dan dokumentasi? Misalnya, untuk angka 69, tulis bahwa ini adalah indikator rata-rata di pasar, dan sekarang konstanta memiliki nama dan konteks. Saya akan menulis komentar bahwa saya mengambil konstanta di situs studi semacam itu. Jika penelitian berubah di masa depan, maka saya akan datang dan memperbarui datanya.

Dengan demikian, kami menjamin bahwa tidak ada angka ajaib yang akan melewati kode kami dan menyulitkannya dari dalam. Mereka membuat jalan mereka melalui memeriksa kompleksitas setiap baris dan berkata: "Ini nomor 4766. Ada apa, aku tidak tahu, atur sendiri!" Ini adalah penemuan hebat bagi saya.

Akibatnya, kami menyadari bahwa kami harus mengikuti ini, dan kami tidak kehilangan nomor ajaib dalam kode. Adalah baik bahwa hampir 100% dari kolega kami setuju dengan kami, dan mereka juga tidak menggunakan angka tersebut.

Tetapi ada pengecualian - ini adalah angka dari βˆ’10 hingga 10, angka 100, 1000 dan sejenisnya, hanya karena mereka sering ditemukan dan tanpa itu sulit. Kami tangguh, tetapi tidak sadis dan berpikir sedikit.

Apakah Anda menggunakan '@staticmethod'?


Mari kita pikirkan apa itu metode statis . Pernahkah Anda bertanya-tanya mengapa itu di Python? Saya tidak. Saya punya Pylint cantik yang mengatakan:

- Dengar, kamu tidak menggunakan self , cls - lakukan metode statis!
- Oke, Pylint, saya akan melakukan metode statis.

Kemudian saya mengajar Python kepada pemula, dan mereka bertanya apa metode statis dan mengapa itu diperlukan. Saya tidak tahu jawabannya dan berpikir apakah mungkin untuk menulis hal yang sama dengan fungsi, atau tidak menggunakan self dalam fungsi biasa, hanya karena itu adalah kelas dan ada sesuatu yang terjadi. Mengapa kita memerlukan konstruksi metode statis?

Saya mencari di Google pertanyaan, dan ternyata sedalam lubang kelinci. Ada banyak bahasa pemrograman lain di mana metode statis juga tidak disukai. Dan beralasan - staticmethod merusak model objek. Akibatnya, saya menyadari - metode statis bukan tempat di sini , dan kami melihatnya. Sekarang, jika kita menggunakan dekorator metode statis, linter akan berkata: "Tidak, maaf, refactor!"

Sebagian besar pengembang tidak setuju dengan saya, tetapi sekitar setengahnya masih berpikir bahwa lebih baik menulis metode biasa atau fungsi reguler daripada metode statis.

Logika dalam __init __. Ru - baik atau buruk?


Ini adalah topik favorit saya. Tentunya, ketika Anda membuat paket baru dan entah bagaimana menyebutnya - itu menciptakan __init __. Ru dan Anda bertanya-tanya apa yang harus dimasukkan ke dalamnya? Apa yang harus dimasukkan dalam __init __ Ru., Dan apa - dalam file berdampingan? Bagi saya, ini adalah pertanyaan yang tidak sepele, dan saya selalu bingung: mungkin sesuatu yang paling penting? Lalu saya berpikir - tidak, sebaliknya, saya akan menempatkan yang paling penting dalam konteks yang paling bisa dimengerti. Jika Anda memasukkan sesuatu ke dalam __init __. Ru, lalu mengimpor semuanya, ternyata impor siklik juga buruk.

Saya melihat berbagai perpustakaan populer, memanjat __init __ Ru mereka, dan memperhatikan bahwa pada dasarnya ada sampah atau kompatibilitas. Bagi saya, pertanyaan ini muncul dengan tajam ketika saya mulai membuat paket besar dengan banyak sub paket - Anda tersesat. , . Python, , , __init__. , 90% .

β€” , API, , - , , ? , , . API . , __init__. - : , , .

, I_CONTROL_CODE β€” . , . , , __init__. β€” . , , , - , .

hasattr ?


hasattr ? , , Python β€” . hasattr , ().

, , hasattr , , . , hasattr, , . - , Python -, hasattr . , . getattr Β« , Β». hasattr β€” getattr, exception .

50 50 β€” , , .



, layer-linter . ? : , , , . , - . - . .

cohesion . , . Cohesion , . False Positive , β€” , , .

vulture Python . - , Python , . ohesion.

Radon , : Halstead , Maintainability Index , . , β€” .

Final type


Final- Python. Typing Extensions, , . , - , β€” , . , - - , ? Tidak perlu . - β€” , , , .

Gratis


, .



, .

, . , . , Python- , .

, Moscow Python Conf++ , . , , Python-.

. . , , , .








Source: https://habr.com/ru/post/id433480/


All Articles