Les commandes telles que cat
sont lues avec le nom de fichier comme argument, mais si aucun nom de fichier n'est donné, l'entrée standard est lue. Cette fois, j'ai étudié comment y parvenir avec Python.
$ cat input.txt
$ cat < input.txt
$ python hoge.py input.txt
$ python hoge.py < input.txt
En Python, l'entrée standard et le pointeur vers le fichier texte sont des objets fichier (plus spécifiquement, des instances de la classe _io.TextIOWrapper
), donc les fonctions suivantes fonctionneront même si l'entrée standard sys.stdin
est donnée en argument. Je vais.
def process(fp):
for line in fp:
print(line, end='')
Que fait cet article avec ce processus externe? Sur ce, nous considérerons trois méthodes.
hoge.py
import argparse
import sys
def main():
parser = argparse.ArgumentParser()
parser.add_argument('filename', nargs='?')
args = parser.parse_args()
if args.filename is None:
process(sys.stdin)
else:
with open(args.filename) as f:
process(f)
if __name__ == "__main__":
main()
C'est un moyen simple de créer des branches selon qu'un argument de ligne de commande est donné. Dans cet article, nous ne considérons pas la gestion spéciale des exceptions pour ʻOSErrorlors de l'exécution de ʻopen ()
ouprocess ()
, mais fermons le fichier même lorsqu'une exception se produit dansprocess ()
. C'est un must.
Si vous ajoutez ʻargparseici, si vous omettez
nargs = '?',
Filename` sera requis.
Cette méthode est très simple à comprendre, mais ce qui n’est pas surprenant, c’est que «process ()» est décrit à deux endroits. Avec un peu plus d'ingéniosité, il peut être assemblé en un seul endroit, mais if-else se sent toujours un peu redondant.
hoge.py
import argparse
import sys
def main():
parser = argparse.ArgumentParser()
parser.add_argument('infile', nargs='?', type=argparse.FileType(),
default=sys.stdin)
args = parser.parse_args()
with args.infile as f:
process(f)
C'est un peu inconnu, mais dans l'ensemble, c'est très rafraîchissant.
En définissant type = argparse.FileType ()
, ʻopen () est appelé au moment de
parse_args () et sa valeur de retour est stockée. À ce stade, si le nom de fichier donné est
-, il sera converti en entrée / sortie standard. Par conséquent, si vous définissez
default = '-', la description sera un peu réduite et ʻimport sys
sera inutile, mais il est difficile à comprendre pour les étrangers, et [Document exemple](https: // docs. python.org/ja/3/library/argparse.html) indique également explicitement default = sys.stdin
.
Et il est normal d'écrire ʻopen () immédiatement après
with`, mais la valeur de retour est la même même pour l'objet fichier lui-même, donc l'opération est la même. Bien que l'importance d'utiliser «comme» soit diminuée.
sys.stdin
n'est généralement pas dérangé d'être utilisé avec l'instruction with
ou d'appelerclose ()
, mais il est bien défini car il s'agit d'un TextIOWrapper. Il est probablement utilisé dans un tel cas. (Source requise)
fileinput
.hoge.py
import argparse
import fileinput
def main():
parser = argparse.ArgumentParser()
parser.add_argument('filenames', nargs='*')
args = parser.parse_args()
with fileinput.input(args.filenames) as f:
process(f)
fileinput.input ()
ouvre les noms de fichiers énumérés les uns après les autres et les convertit en entrée standard si aucun nom de fichier n'est donné.
Même si -
est spécifié comme nom de fichier, l'entrée standard est appelée, donc si vous exécutez $ python hoge.py input.txt -
etc., l'entrée standard sera lue après la lecture de input.txt. Eh bien, ce ne sera pas un gros problème!
Personnellement, je pense que la difficulté est que ce module d'entrée de fichier semble prendre en charge l'entrée standard si vous ne le connaissez pas. Il n'y a pas de place. Je ne pense pas que ce soit un module aussi célèbre ...
Je pense qu'il est préférable d'utiliser la méthode 2 lors de la lecture d'un fichier ** ou ** entrée standard, et la méthode 3 lors de la lecture de plusieurs fichiers ** ou ** entrée standard.
(23/11 postscript) Cliquez ici si vous voulez lire plusieurs fichiers en même temps → [Comment lire des fichiers d'entrée standard ou des fichiers de variables en même temps comme la commande coller en Python](https://qiita.com/hi-asano/ items / de83b18ce4365dd6f793)
Si vous essayez de faire la même chose dans une autre langue, vous devez généralement le faire avec if-else like 1, ce qui est assez difficile? Perl semble être facile.
Recommended Posts