Lekukan dalam Python - Opsi Solusi

Pada sebagian besar bahasa, jika semua lekukan dihapus dalam seluruh kode sumber program dan kemudian autoformatting diterapkan, program akan tetap beroperasi penuh dan pada saat yang sama akan dirancang dengan gaya yang sama.

Tampaknya dalam kasus Python, operasi seperti itu tidak mungkin.

Setidaknya saya tidak bisa menemukan cara untuk mendeteksi indentasi acak Python secara instan. Saya harus menyelesaikan masalah ini sendiri.


pengantar


Pembaca yang terhormat!
Jika pernyataannya dekat dengan Anda:
1) Pemrograman itu merupakan seni yang tinggi.
2) Bahwa ketika memprogram dalam bahasa apa pun Anda perlu memanfaatkan kekuatan dan keragaman bahasa ini untuk meminimalkan kode sumber.
3) Bahwa ketika pemrograman, Anda perlu menunjukkan tingkat tinggi Anda dalam kode sumber program sehingga tidak ada yang bisa mengatakan tentang program Anda bahwa itu "bodoh".

Jika setidaknya satu (!) Dari poin di atas dekat dengan Anda, maka tolong jangan baca artikel ini! Tolong jangan buang waktu Anda di atasnya.
Ini akan berbicara tentang satu momen pemrograman yang sepenuhnya dibuat-buat dan absurd.

Pembaca yang terhormat!
Jika pernyataan sudah dekat dengan Anda:
1) Pemrograman itu adalah pekerjaan rutin, agak monoton, seperti menggali selokan yang tak berujung.
2) Bahwa ketika memprogram dalam bahasa apa pun, Anda perlu menggunakan seperangkat perintah bahasa minimum-optimal tertentu (mungkin membuang sebagian besar perintahnya) sehingga bahkan seorang programmer junior dapat dengan mudah mengetahui program Anda!
3) Bahwa ketika pemrograman program Anda harus sampai batas tertentu "bodoh". Sehingga setelah Anda menerapkannya, Anda dapat memulai proyek baru dan dengan tenang menempatkan programmer junior yang berpartisipasi dalam proyek untuk mendukung dan memperbaikinya di bawah persyaratan baru yang kecil dari pelanggan.

Jika ketiga pernyataan di atas benar untuk Anda, maka mungkin Anda memiliki masalah, solusi yang ingin saya tawarkan.

Kerugian utama dari Python:

1) Python adalah "tidak diminimalkan" dalam penggunaan sumber daya dan datanya dan, oleh karena itu, tidak cocok untuk menulis program yang memerlukan penggunaan sumber daya, seperti aplikasi mobile, program tingkat rendah (driver, program penduduk, dll.) .) dll.

2) Python lambat dan berulir tunggal (GIL - Global Interpreter Lock).

3) Dalam Python, blok program didasarkan HANYA (!) Pada lekukan. Karena ini:

  • “keterbacaan” program berkurang (lihat di bawah);
  • format teks sumber secara otomatis tidak mungkin;
  • ada kemungkinan terjadi kesalahan dengan offset indentasi yang tidak disengaja dan tidak disadari, yang kadang-kadang sangat sulit ditemukan dan diperbaiki.

Kelemahan pertama dari Python adalah sulit untuk kelancaran, dan di sini ia hanya memiliki batasan dalam ruang lingkup penggunaannya. Tetapi ini adalah momen alami, karena tidak mungkin menghasilkan bahasa yang paling efektif di semua bidang tugas.

Kelemahan kedua dari Python adalah ia memiliki interoperabilitas dua arah yang sangat baik dengan C / C ++.

Seringkali proyek yang sukses berkembang cukup pesat. Dan pada awalnya tidak ada persyaratan kinerja tinggi, dan dalam Python, sisipan kecil di C / C ++ digunakan jika perlu.
Tetapi ketika proyek berkembang dan berkembang, persyaratan kinerja meningkat sesuai, dan Python semakin sering mulai memenuhi fungsi-fungsi bahasa yang disebut dari C / C ++. Pada saat yang sama, peran Python itu sendiri tidak menurun, seperti ketika memprogram bagian yang tidak memerlukan kecepatan eksekusi tinggi (dan biasanya ada cukup banyak di proyek besar), Python adalah alat yang lebih nyaman daripada C / C ++.

Dan untuk kelemahan ketiga Python, saya ingin menawarkan solusi saya sendiri.

Anda semua tahu bahwa untuk sebagian besar bahasa format teks teks sumber sangat sering digunakan.

Itu tidak peduli apa lekukan suatu program ditulis dalam bahasa ini, ketika Anda memulai autoformatting, semua lekukan akan dibawa ke bentuk standarnya. Untuk Python, ini sepertinya tidak mungkin.

Setiap programmer yang telah menulis proyek dalam beberapa ribu baris bahasa tahu bahwa proses pengembangan tidak hanya menciptakan bagian selanjutnya dari program dan mengisinya, tetapi terus-menerus memindahkan bagian kode ke subprogram, sekarang di antara blok program, lalu ke modul eksternal umum, dll. P.

Selain itu, dalam praktiknya, pengguna / pelanggan sudah pada tahap awal, setelah bekerja dengan garis besar pertama program, mulai mengubah dan melengkapi tugas-tugas proyek akhir, yang mengarah pada penyesuaian yang kuat dari kode sumber.

Dan kemudian dengan Python, jika terjadi perubahan signifikan dalam lusinan program orang lain (!) (Atau Anda sendiri, tetapi Anda tidak ingat sama sekali), ada baiknya ketika secara tidak sengaja menangkap sepotong kode tambahan milik blok lain saat mentransfer blok, program mungkin tetap beroperasi penuh, tetapi algoritme kerjanya akan berubah (baca “program akan mulai bekerja secara tidak benar”), dan menemukan tempat kesalahan seperti itu dalam program orang lain dan kemudian mengembalikan lekukan dengan benar terkadang sangat sulit!

Dalam hal ini, Anda dapat, tentu saja, melihat teks sumber (sebelum perubahan), tetapi jika Anda telah membuat banyak koreksi di tempat ini, Anda harus “melepas” seluruh rantai koreksi ini.

Memecahkan masalah lekukan dengan Python


Lekukan dalam Python dibentuk oleh perintah-perintah berikut:

- class
- def

- for
- while

- if

- try

- with

Dan untuk menghilangkan ketergantungan pada indentasi, untuk masing-masing perintah ini saya memutuskan untuk menjadikannya aturan untuk menggunakan perintah "final", yang pasti akan menutup blok perintah (indentasi).

Perintah kelas dan def


Untuk perintah kelas / def, biasanya tidak ada masalah menyelesaikan blok indentasi, seperti blok ditutup dengan perintah class / def baru.

Satu-satunya kasus adalah keberadaan satu atau lebih subprogram yang dinyatakan di dalam subprogram / metode lain.

def ppg_1():
    def ppg_2():
        ...  ppg_2 ...
    def ppg_3():
        ...  ppg_3 ...
        ...  ppg_3 ...
        ...  ppg_3 ...
    ...  ppg_1 ...

Kemudian, jika Anda secara tidak sengaja memindahkan blok instruksi dari subprogram internal terakhir, maka ia akan bergabung dengan perintah-perintah dari subprogram / metode di mana subprogram internal ini dinyatakan.

def ppg_1():
    def ppg_2():
        ...  ppg_2 ...
    def ppg_3():
        ...  ppg_3 ...
    ...  ppg_3 ...
    ...  ppg_3 ...
    ...  ppg_1 ...

Dalam hal ini, pada akhir rutin internal / metode ini Anda hanya perlu meletakkan "kembali", yang dengan jelas akan menunjukkan akhir dari blok perintahnya.

def ppg_1():
    def ppg_2():
        ...  ppg_2 ...
    def ppg_3():
        ...  ppg_3 ...
        ...  ppg_3 ...
        ...  ppg_3 ...
        return
    ...  ppg_1 ...

Perintah untuk dan sementara


Pada akhir pernyataan "untuk" dan "sementara" Anda harus memasukkan "lanjutkan".

Itu perintahnya akan terlihat seperti ini:

for  <...> :             #  
    ...  ....
    continue             #  

dan

while  <...> :           #  
    ...  ....
    continue             #  

Contohnya:
        ...  ...

        for i in range(10):
            ...  for ...

            ...  for  ...

            ...  for  ...

        ...  ...

Secara tidak sengaja menghapus lekukan pada perintah terakhir dari blok "for" tidak mengarah pada kesalahan eksekusi program, tetapi mengarah pada hasil yang salah! Dan sangat sulit untuk menemukan kegagalan seperti itu jika Anda tidak mengetahui algoritma program (misalnya, jika itu adalah program seorang kolega yang pensiun)!

Begini caranya:
        ...  ...

        for i in range(10):
            ...  for ...

        ...  for  ...

        ...  for  ...

        ...  ...

Dan dalam contoh di bawah ini, secara tidak sengaja menghapus indentasi akan segera melakukan kesalahan:
        ...  ...

        for i in range(10):
            ...  for ...

            ...  for  ...

            ...  for  ...

            continue

        ...  ...

Jika perintah


Di akhir pernyataan "jika", Anda harus meletakkan perintah "elif 0: pass", dan alih-alih "lain" gunakan perintah "elif 1:".

Itu untuk "jika" akan ada blok perintah yang lengkap:

if <>                      #  
    ...  ....
elif <>
    ...  ....
elif 1:                    #  "else"
    ...  ....
elif 0: pass               #  

Contohnya:
        ...  ...

        if  result != -1 :

            ...  if ...

            ...  if ...

            ...  if ...

        elif 0: pass

        ...  ...

Jika Anda membuatnya seperti yang ditunjukkan di atas, maka di blok perintah "jika ... elif 0: pass", lekukan akan menghasilkan kesalahan startup.

Tanpa "elif 0: pass", jika kemudian indentasi di baris terakhir dari blok "if" terhapus secara tidak sengaja, pertama-tama Anda akan mencari tempat yang menyebabkan program mulai bekerja secara tidak benar, dan kemudian memikirkan indentasi mana yang harus di blok dan yang mana - tidak.
        ...  ...

        if  result != -1 :

            ...  if ...

        ...  if ...

        ...  if ...

        ...  ...

Kenapa lagi, menurut pendapat saya, disarankan untuk menutup blok perintah yang dibuat oleh operator "untuk",
"sementara", "jika", dll ...

karena ketika Anda melihat bagian kode di mana ada perbedaan besar dalam tingkat
indentasi antara akhir arus saat ini blok dan awal berikutnya, Anda sering tidak bisa lagi memahami lekukan mana milik apa.

Kemudian konstruksi dengan "lanjutkan" dan "elif 0: lulus", selain melindungi terhadap penghapusan tidak disengaja, juga akan memungkinkan Anda untuk menentukan unit mana yang dimulai dan menulis komentar di atasnya.

Misalnya, Anda melihat ujung balok besar:

                            ...  ...

                            ...  ...

                            ...  ...

                            ...  ...

                        ...  ...

                        ...  ...

                        ...  ...

                        ...  ...

    elif result == 1 :

        ...  ...

        ...  ...

        ...  ...

        ...  ...

Dan sulit untuk mengingat apa arti setiap level indentasi.

Tapi itu jauh lebih mudah ketika terlihat seperti ini:

                            ...  ...

                            ...  ...

                            ...  ...

                            ...  ...

                            continue    #   b'\\r\\n'   

                        ...  ...

                        ...  ...

                        ...  ...

                        ...  ...

                    elif 0: pass     #  " "  " "

                elif 0: pass         #   . - 

                continue             #    

            continue                 #  .,  -  " "
                      
    elif result == 1 :

        ...  ...

        ...  ...

        ...  ...

        ...  ...

Coba perintah


Ada analogi lengkap dengan "jika".

try:                   #  
    ...  ....
except <...>:
    ...  ....
except 1:              #  "else"
    ...  ....
except 0: pass         #  

Satu-satunya masalah adalah akhirnya: perintah . Setelah itu, Anda tidak dapat lagi memasukkan perintah dari blok percobaan saat ini.

Oleh karena itu, jika ada kebutuhan untuk menggunakannya, maka untuk mempertahankan kemungkinan format-otomatis dan melindungi terhadap indentasi penghapusan yang tidak sengaja, Anda perlu menghapus seluruh blok perintah setelah "akhirnya:" di subprogram lokal (yaitu, menyatakannya sebagai subprogram di dalam subprogram saat ini).

Itu teks dengan "akhirnya:" akan seperti ini:

    def my_ppg():
        ...
        return

    ...

    finally:
        my_ppg()

    ...

Dalam hal ini, Anda juga dapat dengan aman menerapkan autoformatting dan tidak takut
menghapus indentasi secara tidak sengaja.

"Dengan" perintah


Tidak ada perintah tambahan untuk "with" dengan Python yang bisa berfungsi sebagai akhir dari sebuah blok. Oleh karena itu, situasi dengan mirip dengan situasi pada akhirnya.
Itu baik kami mentransfer semua perintah yang dieksekusi di blok pernyataan "dengan" ke subrutin lokal, atau ... Tapi kemudian saya akan mengatakan hal yang sangat menghujat: "... atau Anda tidak perlu menggunakannya."

Faktanya adalah bahwa "dengan", di satu sisi, hanyalah "pembungkus" untuk perintah Python yang ada (yaitu, Anda selalu dapat menggantinya dengan seperangkat perintah serupa), di sisi lain, praktik telah menunjukkan bahwa untuk programmer junior konteks ini Manajer sulit untuk pengembangan penuh. Dan karena itu, jika Anda ingin seorang programmer junior dengan tenang menemani proyek yang diimplementasikan setelah Anda, maka Anda tidak perlu menggunakan tim dalam proyek yang menghambat pekerjaannya.

Kesimpulan



Saya pikir Anda sudah mengerti bahwa jika Anda menulis sebuah program dengan Python menggunakan ANYWHERE (!) Dari teknik-teknik di atas untuk membuat blok indentasi, cukup mudah untuk menulis FULL AUTO FORMATTING program semacam itu bahkan jika Anda condong atau menghapus inden sepenuhnya di dalamnya, karena untuk semua blok perintah ada awal dan akhir blok, terlepas dari indentasi.

Sekarang, sambil tersenyum, kami mengajukan pertanyaan seperti ini: "Apa kerugian dari Python jika Anda memformat blok indentasi dengan benar, berinteraksi dengan C / C ++ jika perlu, dan tidak menggunakan Python dalam aplikasi seluler dan sumber daya yang kritis?"

Jawab: “Hanya kekurangan kecil. Itu pada umumnya - tidak. "

Dan dengan rumusan pertanyaan seperti itu, kita hanya bisa menikmati kelebihan utama Python.

  1. Kesederhanaan.
  2. Siklus pengujian minimum situs: tulis-diluncurkan-diperiksa.
  3. Power - libraries / frameworks untuk Python adalah "untuk setiap selera dan warna."

Ketiga kelebihan ini secara bersama memberikan, menurut pendapat saya, versi bahasa yang hampir sempurna (jangan lupa bahwa ini hanya tunduk pada ketentuan yang ditentukan dalam pertanyaan di atas!).

All Articles