Wie lese ich von stdin oder aus einer Datei, wenn keine Daten in Python geleitet werden?

Ich habe ein CLI-Skript und möchte, dass es Daten aus einer Datei liest. Es sollte in der Lage sein, es auf zwei Arten zu lesen:

  • cat data.txt | ./my_script.py
  • ./my_script.py data.txt

– ein bisschen wie grep , zum Beispiel.

Was ich weiß:

  • sys.argv und optparse lass mich alle Args und Optionen leicht lesen.
  • sys.stdin lass mich die Daten lesen lassen
  • fileinput machen den vollen Prozess automatisch

Unglücklicherweise:

  • Mit fileinput verwendet stdin und alle args als input. So kann ich keine Optionen verwenden, die keine Dateinamen sind, da sie versucht, sie zu öffnen.
  • sys.stdin.readlines() funktioniert gut, aber wenn ich keine Daten sys.stdin.readlines() , hängt es bis ich in Strg + D gehe
  • Ich weiß nicht, wie man implementiert "wenn nichts in stdin, aus einer Datei in args lesen", weil stdin ist immer True in einem booleschen Kontext.

Ich würde gerne eine tragbare Möglichkeit, dies zu tun, wenn möglich.

6 Solutions collect form web for “Wie lese ich von stdin oder aus einer Datei, wenn keine Daten in Python geleitet werden?”

Verarbeiten Sie Ihre Nicht-Dateinamen-Argumente, aber Sie möchten, so dass Sie sich mit einem Array von Nicht-Option-Argumente, dann übergeben Sie das Array als Parameter zu fileinput.input ():

 import fileinput for line in fileinput.input(remaining_args): process(line) 

Argparse erlaubt dies in einer ziemlich einfachen Weise getan werden, und Sie sollten es wirklich verwenden, anstatt optparse wenn Sie Kompatibilitätsprobleme haben.

Der Code würde so etwas machen:

 import argparse parser = argparse.ArgumentParser() parser.add_argument('--input', type = argparse.FileType('r'), default = '-') 

Jetzt hast du einen Parser, der deine Kommandozeilen-Argumente analysiert, eine Datei verwendet, wenn sie einen sieht oder die Standard-Eingabe verwendet, wenn dies nicht der Fall ist.

Für unix / linux können Sie feststellen, ob die Daten durch das Betrachten von os.isatty(0)

 $ date | python -c "import os;print os.isatty(0)" False $ python -c "import os;print os.isatty(0)" True 

Ich bin mir nicht sicher, dass es ein Äquivalent für Windows gibt.

Bearbeiten Ok, ich habe es mit python2.6 auf Windows XP probiert

 C:\Python26>echo "hello" | python.exe -c "import os;print os.isatty(0)" False C:\Python26> python.exe -c "import os;print os.isatty(0)" True 

Also vielleicht ist es nicht alle hoffnungslos für Fenster

Es gibt keine zuverlässige Möglichkeit zu erkennen, ob sys.stdin mit irgendetwas verbunden ist, noch ist es angemessen, dies zu tun (zB der Benutzer möchte die Daten einfügen). Erkennen Sie die Anwesenheit eines Dateinamens als Argument und verwenden Sie stdin, wenn keine gefunden wird.

Ich bin ein Noob, also das könnte nicht eine gute Antwort sein, aber ich versuche, dasselbe zu tun (erlaube eine oder mehrere Dateien auf der Kommandozeile, standardmäßig auf STDIN).

Die letzte Combo, die ich zusammengestellt habe:

 parser = argparse.ArgumentParser() parser.add_argument("infiles", nargs="*") args = parser.parse_args() for line in fileinput.input(args.infiles): process(line) 

Das scheint der einzige Weg, um das gewünschte Verhalten in einem eleganten Paket zu bekommen, ohne dass man Args benannt hat. Genau wie Unix-Befehle werden als solche verwendet:

 cat file1 file2 wc -l < file1 

Nicht:

 cat --file file1 --file file2 

Würde schätzen Feedback / Bestätigung von Veteran idiomatischen Pythonistas, um sicherzustellen, dass ich die beste Antwort bekommen habe. Habe diese Komplettlösung nirgendwo anders gesehen, nur Fragmente.

Sie können diese Funktion verwenden, um festzustellen, ob die Eingabe von einer Pipeline erfolgt oder nicht.

 sys.stdin.isatty() 

Es gibt false zurück, wenn die Eingabe von Pipeline oder true ist.

  • Lesen von stdin im Python-Prozess?
  • Python Lesen von Stdin mit Argumenten
  • Wie kann man Daten zu einem "getpass" wie Passwort-Eingabe umleiten?
  • PowerShell-Wrapper zum direkten Piped-Eingang in Python-Skript
  • Python: Piping Anfragen Bild Argument zu stdin
  • Übergeben von Daten zwischen Python und C # ohne eine Datei zu schreiben
  • Warum kann ich in diesem gegabelten Prozess nicht von Stdin lesen?
  • Kommunizieren Sie mit dem Teilprozess, ohne darauf zu warten, dass der Unterprozess auf Windows beendet wird
  • Ist pythons sys.stdin.read () Block?
  • Benutzerdefinierte Standard-Eingabe für Python-Unterprozess
  • Wie vermeide ich die Verarbeitung eines leeren Stdin mit Python?
  • Python ist die beste Programmiersprache der Welt.