Forum: PC-Programmierung Python3 Call: Rückgabe (stdin) in Variable umleiten


von Jakob (Gast)


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
>>>

: Verschoben durch Moderator
von Sven B. (scummos)


Lesenswert?

subprocess.check_output

von Jakob (Gast)


Lesenswert?

Danke :)

von imonbln (Gast)


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

von Sven B. (scummos)


Lesenswert?

Dann wäre es irgendwie sinnvoller, wenn die Funktion die Uhrzeit einfach 
zurückgibt statt sie auf die Konsole zu schreiben ...

von nicht"Gast" (Gast)


Lesenswert?

Hiho

nun ja, wenn du das eh schon als Python file da hast, kannst du die 
Ausgabe auch gleich Anpassen.

Welchen Grund gibts denn, das nicht zu machnen?

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

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()

https://docs.python.org/3/library/subprocess.html#subprocess.Popen

Gruesse

: Bearbeitet durch User
von PittyJ (Gast)


Lesenswert?

Ich weiss schon, warum ich Python nicht mag. Es gibt nicht mal einfache 
Funktionen für Uhrzeitabfrage. Das muss in einem zweiten Prozess über 
stdio laufen. Wie krank ist das denn.

von Sven B. (scummos)


Lesenswert?

PittyJ schrieb:
> Ich weiss schon, warum ich Python nicht mag. Es gibt nicht mal
> einfache
> Funktionen für Uhrzeitabfrage. Das muss in einem zweiten Prozess über
> stdio laufen. Wie krank ist das denn.

https://docs.python.org/3/library/time.html#time.time

von Sheeva P. (sheevaplug)


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. ;-)

von Sheeva P. (sheevaplug)


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

von Karl (Gast)


Lesenswert?

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

Vergleicht man C mit Python, dann gibt es wohl ehr in C nicht mal die 
einfachsten Dinge.

x = y**3

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.