Subprocess-Modul

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
MarcelF6
User
Beiträge: 226
Registriert: Samstag 3. März 2012, 21:30

Vielen Dank!
Nun funktioniert eigentlich alles.
Ich habe nur noch eine Frage: Warum ist res nachher nicht mehr aufrufbar?

Code: Alles auswählen

process = subprocess.Popen(['python','tok.py'], shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
  stdin = chris
  stdin = stdin.split()
  res = process.communicate(str(stdin))
Wenn ich nämlich per print-Statement res ausgeben möchte, erscheint nur noch: []
Wie kann ich res "richtig" speichern, also mit dem gesamten Inhalt von process.communicate(str(stdin))?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Die Beschreibung passt nicht zu _dem_ Code. `print res` wird hier _immer_ ein Tupel ausgeben, keine Liste.

Also bitte zeig uns den Code um den es eigentlich geht.
MarcelF6
User
Beiträge: 226
Registriert: Samstag 3. März 2012, 21:30

Sorry, hier der momentane Code:

Code: Alles auswählen

import subprocess, os, sys
  f = open("/home/.../text.txt", "r")
  chris = f.read()
  chris = chris.replace("\n","")
  f.close()
  process = subprocess.Popen(['python','tok.py'], shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
  stdin = chris
  stdin = stdin.split()
  res = process.communicate(str(stdin))
Die letzte Zeile gibt eine Liste aus mit den tokenisierten Wörter - also genau das, was ich eigentlich möchte.
Aber diese lässt sich nicht speichern, denn eigentlich bräuchte ich diese Liste als Argument für eine andere Funktion. Aber res ist leer, also: res = [].
Wie kann ich also diese Liste in einer Variable speichern, die ich nachher weiter verwenden kann?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Nochmal: Deine Beschreibung passt nicht zum Verhalten von subprocess.

Code: Alles auswählen

In [1]: import subprocess

In [2]: p = subprocess.Popen(['ls', '/'], stdout=subprocess.P
subprocess.PIPE   subprocess.Popen  

In [2]: p = subprocess.Popen(['ls', '/'], stdout=subprocess.PIPE)

In [3]: p.communicate()
Out[3]: 
('base.key\nbin\nboot\ndev\netc\nhome\ninitrd.img\ninitrd.img.old\nlib\nlib32\nlib64\nlost+found\nmedia\nmnt\nopt\nproc\nroot\nrun\nsbin\nselinux\nsrv\nsys\ntmp\nusr\nvar\nvmlinuz\nvmlinuz.old\n',
 None)

In [4]: _[0]
Out[4]: 'base.key\nbin\nboot\ndev\netc\nhome\ninitrd.img\ninitrd.img.old\nlib\nlib32\nlib64\nlost+found\nmedia\nmnt\nopt\nproc\nroot\nrun\nsbin\nselinux\nsrv\nsys\ntmp\nusr\nvar\nvmlinuz\nvmlinuz.old\n'
Das Ergebnis von `communicate` ist _immer_ ein Tupel, keine Liste, und Stdout das erste Element davon. Stdout wiederum ist _immer_ ein String mit genau der Ausgabe, s.o., keine Liste.

Also bitte zeige mal den wirklichen Inhalt von rest (`repr(res)`) und dazu die Ausgabe von `python tok.py < text.txt`.
MarcelF6
User
Beiträge: 226
Registriert: Samstag 3. März 2012, 21:30

Ahh...vielen Dank!! :)
Du hast mich mit repr(...) gerade auf einen Fehler hingewiesen. Ich versuchte immer, communicate() weiter zu verarbeiten - dabei muss/soll/darf/kann ich das ja gar nicht.
Mit Hilfe von repr(...) konnte ich den Fehler aber beheben - nun funktioniert alles wie gewünscht.
Herzlichen Dank an alle!
BlackJack

@MarcelF6: Du meinst hoffentlich mit Hilfe von `repr()` hast Du den Fehler gefunden und nicht behoben. Du versuchst hier entschieden zu oft Datenstrukturen in Zeichenketten umzuwandeln statt damit richtig zu arbeiten.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Außerdem kann man statt ``python`` noch ``sys.executable`` schreiben, dann funktionierts auch wenn zum Beispiel ``python`` ein Python 3 ist, oder man eine lokale Installation nutzt oder sonstwas.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
MarcelF6
User
Beiträge: 226
Registriert: Samstag 3. März 2012, 21:30

@BlackJack: Ja; so meinte ichs: Ich konnte den Fehler dank repr() finden - und dank dem auch verbesseren. (aber nicht mir repr(), korrekt.)

@Leonideas: Merkwürdig. Mit 'python' funktionierts wunderbar, aber wenn ich 'python' durch 'sys.executable' ersetze (sys bereits importiert), dann kriege ich einen Fehler:
OSError: [Errno 2] No such file or directory
Wir sollen es zwar sowieso per 'python' machen - aber wenns per 'sys.executable' auch funktionieren soll, dann ist das etwas komisch. (Oder müsste man das file tok.py abändern, um 'sys.executable' verwenden zu können?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Also das sys.executable ist natürlich dann kein String mehr - soweit bist du schon, oder?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
MarcelF6
User
Beiträge: 226
Registriert: Samstag 3. März 2012, 21:30

Ah, dann ist es klar, warum der Fehler auftritt.
Ja, ich war soweit. Allerdings habe ich gesehen, dass wir es für die Weiterverarbeitung beim String belassen müssen - daher bleibe ich auch bei 'python'. Danke aber für den Hinweis!
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Was Leonidas meint:

Code: Alles auswählen

process = subprocess.Popen([sys.executable, 'tok.py'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
statt

Code: Alles auswählen

process = subprocess.Popen(['python', 'tok.py'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
Das hat nichts mit den eigentlichen Daten zu tun.
MarcelF6
User
Beiträge: 226
Registriert: Samstag 3. März 2012, 21:30

Ah - tatsächlich. Beide Varianten funktionieren wie erwartet :)
Vielen Dank für den Hinweis!
Antworten