Python3 Call: Rückgabe (stdin) in Variable umleiten

Gast #6110114
Lesenswert?

Ein Python-Programm gibt die Uhrzeit via Print aus. Rufe ich das 
Python-Programm von Python aus als Subprocess auf werden die Uhrzeit und 
das Ergebnis des Aufrufs zurückgegeben.

Wie kann ich die Uhrzeit in eine Variable bekommen?
1
>>> import subprocess
2
>>> subprocess.call("./clock.py")
3
'08:15'
4
0


Das habe ich ohne Erfolg versucht:
1
>>> a, b = subprocess.call("./clock.py")
2
'08:16'
3
Traceback (most recent call last):
4
  File "<stdin>", line 1, in <module>
5
TypeError: 'int' object is not iterable
6
>>>
Gast #6110690
Lesenswert?

Jakob schrieb:
> Ein Python-Programm gibt die Uhrzeit via Print aus. Rufe ich das
> Python-Programm von Python aus als Subprocess auf werden die Uhrzeit und
> das Ergebnis des Aufrufs zurückgegeben.

Ist sicher eine Super Idee wenn ein Python Programm ein zweites per 
Subprocess aufruft, Kostet ja auch nichts wenn 2 Prozesse gestartet 
werden müssen und zwei Python Interpreter laufen.

kannst du das clock.py nicht importieren und die Funktion daraus dann 
manuell aufrufen. das stdout kann man dann mit 
contextlib.redirect_stdout contextmanager umleiten.

https://docs.python.org/3/library/contextlib.html#contextlib.redirect_stdout
#6119541
Lesenswert?

PittyJ schrieb:
> Ich weiss schon, warum ich Python nicht mag.

Vermutlich magst Du Python nur deswegen nicht, weil Du nicht den 
leisesten Hauch einer Ahnung davon hast. "\(".)/"

> Es gibt nicht mal einfache Funktionen für Uhrzeitabfrage.

Aber natürlich gibt es die: die Funktion time() aus dem Modul time, was 
für eine Überraschung. Für verschiedene Repräsentationen als 
Zeichenfolge gibts in demselben Modul noch weitere Funktionen, wie etwa 
strftime().

> Das muss in einem zweiten Prozess über stdio laufen. Wie krank ist
> das denn.

Das liegt nicht an Python, sondern am TO, der offensichtlich ähnlich 
wenig Ahnung von Python hat wie Du. ;-)
#6119543
Lesenswert?

Kaj G. schrieb:
> Statt call Popen nutzen.
>
1
> from subprocess import Popen, PIPE
2
> 
3
> proc = Popen(['./clock.py',], stdout=PIPE, stderr=PIPE)
4
> out, err = proc.communicate()
5
>

Nicht als Kritik, sondern nur als Hinweis gedacht:

Direkt nach dem Instanziieren eines subprocess.Popen-Objekts darauf die 
Methode communicate() aufzurufen, ist irgendwie widersinnig. 
communicate() blockt nämlich: "Interact with process: Send data to 
stdin. Read data from stdout and stderr, until end-of-file is reached. 
Wait for process to terminate." [1]

Aber wenn ich gleich nach dem Starten des Subprozesses ohnehin blocke, 
bis der Subprozess beendet ist, kann ich mich gleich an die erste 
Empfehlung halten: "The recommended approach to invoking subprocesses is 
to use the run() function for all use cases it can handle. For more 
advanced use cases, the underlying Popen interface can be used 
directly." [2]

Kurz gesagt: Einen Unterprozeß zu starten, sein Ende abzuwarten, seinen 
Rückgabewert zu checken, und am Ende stdout und / oder stderr 
auszulesen, ist kein "advanced use case" und braucht kein Popen. Dafür 
reicht bereits die Funktion subprocess.run() vollkommen aus. Sie gibt 
eine Instanz von subprocess.CompletedProcess zurück, aus deren Membern 
returncode, stdout, und stderr die gewünschten Informationen bezogen 
werden können.

Ein Anwendungsfall für subprocess.Popen ist zum Beispiel, wenn man mit 
dem Subprozess tatsächlich interagieren will, also die Ausgaben auf 
stdout und / oder stderr schon während der Laufzeit des Prozesses 
mitlesen und darauf reagieren möchte, etwa indem man etwas an stdin oder 
ein Signal schickt.

Nichtsdestotrotz erscheint es natürlich etwas merkwürdig, was der TO 
hier macht, denn die Rückgabe der aktuellen Uhrzeit in Minuten und 
Sekunden als String geht ganz easy über
1
import time
2
time.strftime('%H:%M')

Mit dem Modul datetime kann dabei sogar hübsch herumgerechnet werden:
1
import datetime
2
uhrzeit_vor_drei_minuten = (
3
    datetime.datetime.now() - datetime.timedelta(minutes=3)
4
).strftime('%H:%M')

Ein Teufelszeug, dieses Python. ;-)


[1] 
https://docs.python.org/3/library/subprocess.html#subprocess.Popen.communicate

[2] https://docs.python.org/3/library/subprocess.html#subprocess.run

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren