Indentation en Python - Option Solution

Dans la grande majorité des langues, si toute indentation est supprimée dans tout le code source du programme, puis la mise en forme automatique est appliquée, le programme restera pleinement opérationnel et en même temps sera conçu dans le même style.

Il semblerait que dans le cas de Python, une telle opération ne soit pas possible.

Au moins, je n'ai trouvé nulle part comment détecter instantanément des retraits décalés de manière aléatoire en Python. J'ai dû résoudre ce problème moi-même.


introduction


Cher lecteur!
Si la déclaration est proche de vous:
1) Que la programmation est un art élevé.
2) Que lors de la programmation dans n'importe quel langage, vous devez tirer le meilleur parti de la puissance et de la diversité de ce langage pour minimiser le code source.
3) Que lors de la programmation, vous devez montrer votre niveau élevé dans le code source du programme afin que personne ne puisse dire de votre programme qu'il est "stupide".

Si au moins un (!) Des points ci-dessus est proche de vous, alors ne lisez pas cet article! Ne perdez pas votre temps dessus.
Il parlera d'un moment de programmation complètement farfelu et absurde.

Cher lecteur!
Si la déclaration est déjà proche de vous:
1) Cette programmation est un travail de routine, plutôt monotone, tout comme creuser un fossé sinueux sans fin.
2) Que lors de la programmation dans n'importe quel langage, vous devez utiliser un certain ensemble minimum-optimal de commandes de langage (en supprimant éventuellement la plupart de ses commandes) afin que même un programmeur débutant puisse facilement comprendre votre programme!
3) Que lors de la programmation de votre programme devrait être dans une certaine mesure «stupide». Pour qu'après l'avoir mis en œuvre, vous puissiez démarrer un nouveau projet et placer calmement le programmeur junior qui a participé au projet pour le soutenir et l'affiner sous les nouvelles petites exigences régulières du client.

Si toutes ces trois affirmations ci-dessus sont vraies pour vous, alors vous avez peut-être un problème, dont je veux proposer la solution.

Les principaux inconvénients de Python:

1) Python n'est "pas minimisé" dans l'utilisation des ressources et de ses données et, par conséquent, ne convient pas pour écrire des programmes qui nécessitent une utilisation des ressources, tels que des applications mobiles, des programmes de bas niveau (pilotes, programmes résidents, etc.) .) etc.

2) Python est lent et monothread (GIL - Global Interpreter Lock).

3) En Python, les blocs de programme sont basés UNIQUEMENT (!) Sur l'indentation. À cause de ce:

  • la «lisibilité» des programmes diminue (voir ci-dessous);
  • la mise en forme automatique complète du texte source est impossible;
  • il est probable qu'une erreur se produise avec un décalage accidentel et inaperçu des retraits, ce qui est parfois très difficile à trouver et à corriger.

Le premier inconvénient de Python est difficile à lisser, et ici il a juste une limitation dans la portée de son utilisation. Mais c'est un moment naturel, car il est impossible de trouver une langue qui serait la plus efficace dans tous les domaines des tâches.

Le deuxième inconvénient de Python est qu'il présente une excellente interopérabilité bidirectionnelle avec C / C ++.

Souvent, un projet réussi se développe assez rapidement. Et au début, il n'y a pas d'exigences de performances élevées, et en Python, de minuscules insertions en C / C ++ sont utilisées si nécessaire.
Mais à mesure que le projet se développe et se développe, les exigences de performances augmentent en conséquence, et Python commence de plus en plus souvent à remplir les fonctions du langage appelé à partir de C / C ++. Dans le même temps, le rôle de Python lui-même ne diminue pas, car lors de la programmation de sections qui ne nécessitent pas une vitesse d'exécution élevée (et il y en a généralement beaucoup dans les grands projets), Python est un outil plus pratique que C / C ++.

Et pour le troisième inconvénient de Python, je voudrais proposer ma propre solution.

Vous savez tous que pour la grande majorité des langues, le formatage automatique du texte source est très souvent utilisé.

Ceux. quelle que soit l'indentation qu'un programme est écrit dans cette langue, lorsque vous démarrez la mise en forme automatique, toute l'indentation sera ramenée à sa forme standard. Pour Python, cela semble impossible.

Tout programmeur qui a écrit des projets dans plusieurs milliers de lignes du langage sait que le processus de développement n'invente pas seulement le prochain morceau du programme et le remplit, mais déplace constamment des sections du code vers le sous-programme, maintenant entre les blocs de programme, puis vers des modules externes communs, etc. P.

De plus, dans la pratique, les utilisateurs / clients déjà au stade initial, ayant travaillé avec la première ébauche du programme, commencent à modifier et à compléter les tâches du projet final, ce qui conduit à un fort ajustement du code source.

Et puis en Python, en cas de changement significatif de dizaines de morceaux du programme (!) De quelqu'un d'autre (ou du vôtre, mais dont vous ne vous souvenez pas du tout), cela vaut la peine d'attraper accidentellement un morceau de code supplémentaire appartenant à un autre bloc lors du transfert d'un bloc, le programme peut rester pleinement opérationnel, mais l'algorithme de son travail va changer (lire "le programme va commencer à fonctionner incorrectement"), et trouver la place d'une telle erreur dans un programme étranger puis restaurer correctement l'indentation est parfois très difficile!

Dans ce cas, vous pouvez bien sûr voir le texte source (avant les modifications), mais si vous avez déjà fait beaucoup de corrections à cet endroit, vous devrez «dérouler» toute cette chaîne de corrections.

Résolution du problème d'indentation en Python


L'indentation en Python est formée par les commandes suivantes:

- class
- def

- for
- while

- if

- try

- with

Et pour supprimer la dépendance à l'indentation, pour chacune de ces commandes, j'ai décidé d'en faire une règle pour utiliser la commande «finale», qui fermera définitivement le bloc de commandes (indentation).

Commandes de classe et def


Pour les commandes class / def, il n'y a généralement pas de problème pour terminer le bloc d'indentation, car le bloc est fermé avec la nouvelle commande class / def.

Le seul cas est la présence d'un ou plusieurs sous-programmes déclarés dans un autre sous-programme / méthode.

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

Ensuite, si vous déplacez accidentellement le bloc d'instructions du dernier sous-programme interne, il fusionnera avec les commandes du sous-programme / méthode dans lequel ce sous-programme interne est déclaré.

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

Dans ce cas, à la fin de cette routine / méthode interne, il vous suffit de mettre "return", qui indiquera clairement la fin du bloc de ses commandes.

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

Les commandes for et while


À la fin des instructions "for" et "while", vous devez mettre "continue".

Ceux. la commande ressemblera à ceci:

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

et

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

Par exemple:
        ...  ...

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

            ...  for  ...

            ...  for  ...

        ...  ...

La suppression accidentelle de l'indentation dans les dernières commandes du bloc «for» ne conduit pas à une erreur d'exécution du programme, mais conduit à des résultats erronés! Et il est très difficile de trouver un tel échec si vous ne connaissez pas l'algorithme du programme (par exemple, si c'est le programme d'un collègue qui prend sa retraite)!

Voici comment:
        ...  ...

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

        ...  for  ...

        ...  for  ...

        ...  ...

Et dans l'exemple ci-dessous, la suppression accidentelle du retrait provoquera immédiatement une erreur:
        ...  ...

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

            ...  for  ...

            ...  for  ...

            continue

        ...  ...

Commande if


À la fin de l'instruction "if", vous devez mettre la commande "elif 0: pass", et au lieu de "else", utilisez la commande "elif 1:".

Ceux. pour "si" il y aura un bloc complet de commandes:

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

Par exemple:
        ...  ...

        if  result != -1 :

            ...  if ...

            ...  if ...

            ...  if ...

        elif 0: pass

        ...  ...

Si vous le faites comme indiqué ci-dessus, alors dans le bloc de commande «if ... elif 0: pass», l'indentation générera une erreur de démarrage.

Sans «elif 0: pass», si les retraits dans les dernières lignes du bloc «if» sont supprimés accidentellement, vous chercherez d'abord l'endroit qui a fait que le programme a commencé à fonctionner de manière incorrecte, puis pensez aux retraits qui devraient être dans le bloc et lesquels - non.
        ...  ...

        if  result != -1 :

            ...  if ...

        ...  if ...

        ...  if ...

        ...  ...

Sinon, à mon avis, il est conseillé de fermer les blocs de commandes créés par les opérateurs "pour",
"tandis que", "si", etc. ...

parce que lorsque vous regardez une section de code où il y a une grande différence dans le niveau d'
indentation entre la toute fin du courant bloc et le début du suivant, vous ne pouvez souvent plus comprendre quelle indentation appartient à quoi.

Ensuite, les constructions avec «continuer» et «elif 0: passer», en plus de vous protéger contre une suppression accidentelle, vous permettront également d'indiquer avec quel bloc vous avez commencé et d'écrire un commentaire dessus.

Par exemple, vous voyez la fin d'un grand bloc:

                            ...  ...

                            ...  ...

                            ...  ...

                            ...  ...

                        ...  ...

                        ...  ...

                        ...  ...

                        ...  ...

    elif result == 1 :

        ...  ...

        ...  ...

        ...  ...

        ...  ...

Et il est difficile de se rappeler ce que signifie chaque niveau d'indentation.

Mais c'est beaucoup plus facile quand cela ressemble à ceci:

                            ...  ...

                            ...  ...

                            ...  ...

                            ...  ...

                            continue    #   b'\\r\\n'   

                        ...  ...

                        ...  ...

                        ...  ...

                        ...  ...

                    elif 0: pass     #  " "  " "

                elif 0: pass         #   . - 

                continue             #    

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

        ...  ...

        ...  ...

        ...  ...

        ...  ...

Commande try


Il y a une analogie complète avec «si».

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

Le seul problème est le enfin: commande . Après cela, vous ne pouvez plus placer aucune des commandes du bloc d'essai actuel.

Par conséquent, s'il est nécessaire de l'utiliser, afin de préserver la possibilité de formatage automatique et de vous protéger contre la suppression accidentelle de retraits, vous devez supprimer le bloc entier de commandes après «enfin:» dans le sous-programme local (c'est-à-dire le déclarer comme sous-programme dans le sous-programme actuel).

Ceux. le texte avec "finalement:" sera comme ceci:

    def my_ppg():
        ...
        return

    ...

    finally:
        my_ppg()

    ...

Dans ce cas, vous pouvez également appliquer la mise en forme automatique en toute sécurité et ne pas avoir peur de
supprimer accidentellement des retraits.

Commande "Avec"


Il n'y a pas de commandes supplémentaires pour «avec» en Python qui pourraient servir de fin de bloc. Par conséquent, la situation avec est similaire à la situation avec finalement.
Ceux. soit nous transférons toutes les commandes qui sont exécutées dans le bloc d'instructions "avec" vers le sous-programme local, soit ... Mais alors je dirai une chose terriblement blasphématoire: "... ou vous n'avez simplement pas besoin de l'utiliser."

Le fait est que «avec», d'une part, n'est qu'un «wrapper» pour les commandes Python existantes (c'est-à-dire que vous pouvez toujours le remplacer par un ensemble similaire de commandes), d'autre part, la pratique a montré que pour les programmeurs débutants, ce contexte Le gestionnaire est difficile pour un développement complet. Et donc, si vous voulez qu'un programmeur junior accompagne calmement le projet implémenté après vous, alors vous n'avez pas besoin d'utiliser des équipes dans le projet qui gênent son travail.

Conclusion



Je pense que vous avez déjà compris que si vous écrivez un programme en Python en utilisant N'IMPORTE O ((!) Parmi les techniques ci-dessus pour créer des blocs d'indentation, il est assez facile d'écrire un FORMATAGE COMPLÈTE AUTOMATIQUE d'un tel programme même si vous inclinez ou supprimez complètement les retraits, car pour tous les blocs de commande, il y a un début et une fin de bloc, indépendamment de l'indentation.

Maintenant, avec un sourire, nous posons la question comme celle-ci: "Quels sont les inconvénients de Python si vous formatez correctement les blocs d'indentation, si vous interagissez avec C / C ++ si nécessaire, et si vous n'utilisez pas Python dans les applications mobiles et les ressources critiques?"

Réponse: «Seulement des défauts mineurs. Ceux. en gros - non. "

Et avec une telle formulation de la question, nous ne pouvons que profiter des principaux avantages de Python.

  1. Simplicité.
  2. Cycle de test minimum des sites: écrit-lancé-vérifié.
  3. Power - les bibliothèques / frameworks pour Python sont "pour tous les goûts et toutes les couleurs".

Ces trois avantages réunis donnent, à mon avis, une version presque parfaite de la langue (n'oubliez pas que cela n'est soumis qu'aux conditions spécifiées dans la question ci-dessus!).

All Articles