2016-04-19 1 views
1

Je suis novice en Python et je connais à peine les listes et les tuples. J'ai un programme à exécuter qui prend plusieurs valeurs comme argument d'entrée. Ci-dessous la liste des args d'entréePython passe plusieurs chaînes à un seul argument de ligne de commande

parser = argparse.ArgumentParser() 
parser.add_argument("server") 
parser.add_argument("outdir") 
parser.add_argument("dir_remove", help="Directory prefix to remove") 
parser.add_argument("dir_prefix", help="Directory prefix to prefix") 
parser.add_argument("infile", default=[], action="append") 
options = parser.parse_args() 

Le programme fonctionne très bien avec la commande suivante

python prod2dev.py mysrv results D:\Automations D:\MyProduction Automation_PP_CVM.xml 

Mais en regardant le code, il semble que le code peut accepter plusieurs noms de fichiers pour argument « infile » . J'ai essayé de suivre pour passer plusieurs noms de fichiers, mais aucun n'a fonctionné.

python prod2dev.py mysrv results D:\Automations D:\MyProduction "Automation_PP_CVM.xml, Automation_PT_CVM.xml" 

python prod2dev.py mysrv results D:\Automations D:\MyProduction ["Automation_PP_CVM.xml", "Automation_PT_CVM.xml"] 

python prod2dev.py mysrv results D:\Automations D:\MyProduction ['Automation_PP_CVM.xml', 'Automation_PT_CVM.xml'] 

python prod2dev.py mysrv results D:\Automations D:\MyProduction ['"Automation_PP_CVM.xml"', '"Automation_PT_CVM.xml"'] 

Le code ci-dessous parcourt la liste apparemment

infile = windowsSucksExpandWildcards(options.infile) 
for filename in infile: 
    print(filename) 
    outfilename = os.path.join(options.outdir, os.path.split(filename)[1]) 
    if os.path.exists(outfilename): 
     raise ValueError("output file exists: {}".format(outfilename)) 

    with open(filename, "rb") as f: 
     root = lxml.etree.parse(f) 
    if not isEnabled(root): 
     print("Disabled. Skipping.") 
     continue 
    elif not hasEnabledTriggers(root): 
     print("Has no triggers") 
     continue 
... 
... 
... 
def windowsSucksExpandWildcards(infile): 
    result = [] 
    for f in infile: 
     tmp = glob.glob(f) 
     if bool(tmp): 
      result.extend(tmp) 
     else: 
      result.append(f) 
    return result 

S'il vous plaît guider sur la façon de passer plusieurs noms de fichiers (chaînes) à un seul argument « infile » qui est apparemment une liste.

Je suis en Python 3.5.1 | Anaconda 4.0.0 (32 bits)

Répondre

3

Vous passez l'argument nargs, non action="append":

parser.add_argument("infile", default=[], nargs='*') 

* signifie zéro ou plus, comme dans les expressions régulières. Vous pouvez également utiliser + si vous en avez besoin d'au moins un. Comme vous avez une valeur par défaut, je suppose que l'utilisateur n'est pas obligé d'en transmettre.

+0

Et quelle est la meilleure façon d'appeler le programme? – Ali

+0

@Ali: Tout comme votre premier essai, mais sans les guillemets et sans les virgules. Les guillemets sont utilisés pour faire quelque chose d'un argument qui serait plus d'un. Dans ce cas, ils doivent être des arguments séparés. Les virgules sont interprétées comme des virgules, pas comme des délimiteurs. L'espace est le délimiteur. – zondo

0

Votre code, d'après tout ce que vous avez posté, semble solide.

Le problème est avec l'extrait que vous avez posté qui est censé traverser la liste. La façon dont votre programme est configuré, vous ne pouvez pas utiliser infile comme une variable

Tout ce que vous devez faire pour y remédier est passer infile avec options.infile

Plus précisément:

for filename in options.infile: 
    print(filename) 

La raison est tout votre les arguments sont stockés dans les options "Namespace" -type variable

+0

Mon mauvais. Je voulais cacher la complexité. S'il vous plaît voir mon edit – Ali