7
votes

Traitement des arguments de ligne de commande en notation de préfixe en python

J'essaie d'analyser une ligne de commande dans Python qui ressemble à ce qui suit: xxx

En d'autres termes, la commande prend un nombre illimité d'arguments, et chaque argument peut éventuellement être précédé d'une option -o qui concerne spécifiquement cet argument. Je pense que cela s'appelle une "notation de préfixe".

dans la coquille de Bourne, je ferais quelque chose comme ce qui suit: xxx

regarder autour de la bash tutoriels, etc. Cela semble être l'idiome accepté, donc je suppose que Bash est optimisé pour travailler avec des arguments de ligne de commande de cette façon.

Essayer de mettre en œuvre ce modèle en Python, ma première supposition était de Utilisez pop () , car il s'agit essentiellement d'une opération de pile. Mais je suppose que cela ne fonctionnera pas aussi sur Python, car la liste des arguments dans sys.argv est dans le mauvais ordre et devrait être traité comme une file d'attente (c.-à-d. POP de la gauche de gauche à gauche ). J'ai lu que les listes ne sont pas optimisées pour être utilisées comme files d'attente dans Python.

Alors, mes idées sont: Convertissez argv à un collections.deque et utilisez popleft () , inverse argv à l'aide de inverse () et utilisez pop () , ou peut-être juste travailler Avec les indices de la liste INT eux-mêmes.

Est-ce que quelqu'un sait-il d'une meilleure façon de le faire, sinon laquelle de mes idées serait la meilleure-pratique en python?


0 commentaires

6 Réponses :


6
votes

Vous pouvez faire

o_flag = False
for a in argv:
    if a == '-o':
        o_flag = True
        continue
    # do whatever
    o_flag = False


2 commentaires

Vous avez raison; Je pourrais facilement mettre en œuvre ce modèle en C si la performance était la plus importante. Je suppose que ma question est davantage sur la mise en œuvre de ARGV et de la meilleure façon d'y accéder comme une pile (car elle doit être une pile en interne).


Je suppose que ce serait un tableau C standard, même si comme je l'ai dit, je ne sais pas avec certitude. Vous pouvez toujours jeter un coup d'œil au code source de l'interprète Python et essayer de suivre la mise en œuvre de la matrice, si vous êtes curieux. Mais pour une utilisation dans la pratique, cela n'a pas d'importance.



3
votes

quelque chose comme: xxx

devrait bien fonctionner pour vous. Sauf si vous attendez un très grand nombre d'arguments, j'irais que tout le code est le plus simple (et ne vous inquiétez pas trop sur la performance). L'ARGV [1:] ignore cette première valeur ARGV, qui sera le nom du script.


0 commentaires


7
votes

1 commentaires

J'aimerais savoir sur argparse. OptParse est bien mais si vous voulez que votre argument ait plusieurs valeurs, vous devez faire votre propre classe. Pourquoi tant d'analyses d'options dans la STDLIB?



7
votes

Un équivalent fonctionnel Python de "Shift" dans Bourne / Bash peut être utilisé par l'importation de SYS, puis affectant Sys.ARGV [1:] à une variable, par exemple. "arguments". Ensuite, vous pouvez utiliser args = args [1:] pour vous déplacer à gauche une fois ou utiliser un nombre plus élevé pour passer plusieurs fois. L'indice d'argument va partir de 0, plutôt que 1. L'exemple ci-dessus pourrait ressembler à:

import sys
args = sys.argv[1:]
while len(args):
    if args[0] == '-o':
        option = args[1]
        args = args[2:] # shift 2
    # Work with args[0] (the argument) and option (the option)
    # ...
    args = args[1:] # shift


0 commentaires

1
votes

in python delys.argv [1] code> fait la même opération que shift code> dans bash code>. En Python sys.argv code> est une liste. Suppression de l'élément sur l'index 1 code> est identique que shift code> dans BASH code>.

Sous le script Python d'échantillon aidera à sauter -o code> dans les arguments et considérez tous les autres arguments. P>

#!/usr/bin/python
import sys

if __name__ == '__main__':
    while len(sys.argv) > 1:
        if sys.argv[1] != "-o":
            print sys.argv[1]
        del sys.argv[1]


0 commentaires