Python: Äquivalent der Eingabe mit sys.stdin

Ich möchte einige (python 3) Code testen, der direkt die print und input verwendet. Wie ich es verstehe, ist der einfachste Weg, dies zu tun, durch Abhängigkeitsinjektion: Ändern des Codes, so dass es Eingabe- und Ausgabeströme als Argumente verwendet, wobei sys.stdin und sys.stdout standardmäßig verwendet werden und während des Testens die Spottobjekte übergeben werden. Es ist offensichtlich, was mit print zu tun ist:

 print(text) #replaced with... print(text, file=output_stream) 

Der input hat jedoch keine Argumente für Ein- und Ausgabeströme. Entspricht der folgende Code korrekt sein Verhalten?

  • Wie kann ich die vorherigen Ausnahmen leichter unterdrücken, wenn ich meine eigene Ausnahme als Antwort aufnehme?
  • Cx_Freeze ausführbare Datei funktioniert nicht mit pygame
  •  text = input(prompt) #replaced with... print(prompt, file=output_stream, end='') text = input_stream.readline()[:-1] 

    Ich hatte einen Blick auf die Implementierung von input , und es macht ziemlich viel Magie, ruft sys.stdin.fileno und untersucht sys.stdin.encoding und sys.stdin.errors anstatt nennen irgendwelche der read* Methoden – ich würde Ich weiß, wo ich anfangen soll, diese zu verspotten.

  • Wie kann man NDB-Cache in Tests löschen / ungültig machen
  • Wie man den Cache für socket.gethostbyname Antwort aufhebt?
  • Flask: Caching statischer Dateien (.js, .css)
  • Python threadsafe objekt cache
  • Chronisch veraltete Ergebnisse mit MySQLdb in Python
  • Löschen * .pyc
  • 2 Solutions collect form web for “Python: Äquivalent der Eingabe mit sys.stdin”

    input() nur die Magie, die du erwähnt hast, wenn stdin und stdout nicht verändert werden, denn nur dann kann es Dinge wie die readline Bibliothek verwenden. Wenn Sie sie mit etwas anderem ersetzen (echt-Dateien oder nicht), kommt es auf diesen Code:

     /* Fallback if we're not interactive */ if (promptarg != NULL) { if (PyFile_WriteObject(promptarg, fout, Py_PRINT_RAW) != 0) return NULL; } tmp = _PyObject_CallMethodId(fout, &PyId_flush, ""); if (tmp == NULL) PyErr_Clear(); else Py_DECREF(tmp); return PyFile_GetLine(fin, -1); 

    Wo PyFile_GetLine die readline Methode aufruft . So wird das Verspotten sys.std* funktionieren.

    Es wird empfohlen, dies mit dem try: finally: tun try: finally: ein Kontext-Prozessor oder das mock Modul, so dass die Ausgänge wiederhergestellt werden, auch wenn der Code, den Sie testen, mit Ausnahmen fehlschlägt:

     from unittest.mock import patch from io import StringIO with patch("sys.stdin", StringIO("FOO")), patch("sys.stdout", new_callable=StringIO) as mocked_out: x = input() print("Read:", x) assert mocked_out.getvalue() == "Read: FOO\n" 

    Wenn Sie dem sys.stdin ein Datei-ähnliches Objekt sys.stdin die input Python anstelle der Standard-Eingabe verwendet. Aber denken Sie daran, sys.stdin wieder zu dem Standard-Eingang sys.stdin , nachdem Sie damit fertig sind. Der gleiche Trick gilt für sys.stdout . Du kannst so etwas machen:

     original_stdin = sys.stdin sys.stdin = open('inputfile.txt', 'r') original_stdout = sys.stdout sys.stdout = open('outputfile.txt', 'w') response = input('say hi: ') print(response) sys.stdin = original_stdin sys.stdout = original_stdout 

    Diese beiden Linien

     response = input('say hi: ') print(response) 

    Wird anstelle der Standard-Eingabe und der Standardausgabe spezifizierte Dateien ( inputfile.txt und outputfile.txt ) verwenden.

    UPDATE: Wenn Sie nicht mit physischen Dateien umgehen wollen, schauen Sie sich das Modul an. Es bietet die io.StringIO Klasse, mit der Sie In-Memory-Textstromoperationen ausführen können.

     original_stdin = sys.stdin sys.stdin = io.StringIO('input string') original_stdout = sys.stdout sys.stdout = io.StringIO() response = input('say hi: ') print(response) output = sys.stdout.getvalue() sys.stdin = original_stdin sys.stdout = original_stdout print(output) 
    Python ist die beste Programmiersprache der Welt.