Pour ceux qui souhaitent une réponse plus explicite, voici comment j'ai finalement mis en œuvre la suggestion de @hpaulj :
J'ai d'abord défini un groupe d'arguments pour les arguments des fichiers d'entrée et de sortie :
files = parser.add_argument_group('file arguments:',description='These arguments can also be provided as postional arguments, in which case the input file comes first.')
files.add_argument('-i', '--input', nargs='?',
help='Source of the words to be syllabified. If None or -, then input will be read from stdin.',
dest='inputfile')
files.add_argument('-o', '--output-file', nargs='?',
help='Destination of the syllabified words. If None or -, then ouput will be written to stdout.',
dest='outputfile')
files.add_argument('fileone',nargs='?',
help=argparse.SUPPRESS)
files.add_argument('filetwo',nargs='?',
help=argparse.SUPPRESS)
Cela m'a permis de garder les arguments ensemble, séparément des autres arguments du programme, et m'a donné un peu plus de contrôle sur la façon dont le texte d'aide apparaîtrait pour qu'il ait le plus de sens possible.
Ensuite, après avoir analysé les arguments ( args = parser.parse_args()
), j'ai ajouté la logique suivante pour déterminer quelles étaient les entrées et sorties correctes et pour ouvrir les fichiers ou stdin et stdout comme il convient :
if (args.inputfile == None or args.inputfile == '-'):
if (args.outputfile == None or args.outputfile == '-'):
if (args.fileone == None or args.fileone == '-') and (args.filetwo == None or args.filetwo == '-'):
input = sys.stdin
output = sys.stdout
elif args.fileone != None and (args.filetwo == None or args.filetwo == '-'):
try:
input = open(args.fileone,'r')
output = sys.stdout
except:
input = sys.stdin
output = open(args.fileone,'w')
else:
input = open(args.fileone,'r')
output = open(args.filetwo,'w')
else:
if (args.fileone == None or args.fileone == '-') and (args.filetwo == None or args.filetwo == '-'):
input = sys.stdin
output = open(args.outputfile,'w')
elif args.fileone != None and (args.filetwo == None or args.filetwo == '-'):
input = open(args.fileone,'r')
output = open(args.outputfile,'w')
else:
print("Error: too many files")
print("Both -o and positional output file given")
sys.exit(1)
else:
if (args.outputfile == None or args.outputfile == '-'):
if (args.fileone == None or args.fileone == '-') and (args.filetwo == None or args.filetwo == '-'):
input = open(args.inputfile,'r')
output = sys.stdout
elif args.fileone != None and (args.filetwo == None or args.filetwo == '-'):
input = open(args.inputfile,'r')
output = open(args.fileone,'w')
else:
print("Error: too many files")
print("Both -i and positional input file give")
sys.exit(1)
else:
if (args.fileone == None or args.fileone == '-') and (args.filetwo == None or args.filetwo == '-'):
input = open(args.inputfile,'r')
output = open(args.outputfile,'w')
elif args.fileone != None and (args.filetwo == None or args.filetwo == '-'):
print("Error: too many files")
print("Both -i and -o given with a positional file")
sys.exit(1)
else:
print("Error: too many files")
print("Both -i and -o given with positional files")
sys.exit(1)
Comme vous pouvez le voir, j'ai décidé d'accepter à la fois la version par défaut de l'option None
y -
comme possibilités de se référer à stdin/stdout. Cela reproduit le comportement de la fonction FileType
qui a également accepté -
de cette manière.
La seule ambiguïté qui subsiste est que "None"
(c'est-à-dire une chaîne de caractères du mot "None") n'est pas la même chose que None
(c'est-à-dire la classe NoneType) et les messages d'aide pourraient être interprétés comme impliquant que -i None
doit faire référence à stdin. Cependant, je me suis dit que la différence ici devrait être suffisamment évidente pour la plupart des utilisateurs de python pour que je ne complique pas davantage la logique pour tenir compte de cette possibilité.