Seite 1 von 2

Re: Subprocess-Modul

Verfasst: Montag 9. April 2012, 19:49
von MarcelF6
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))?

Re: Subprocess-Modul

Verfasst: Montag 9. April 2012, 19:52
von cofi
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.

Re: Subprocess-Modul

Verfasst: Montag 9. April 2012, 20:16
von MarcelF6
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?

Re: Subprocess-Modul

Verfasst: Montag 9. April 2012, 20:59
von cofi
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`.

Re: Subprocess-Modul

Verfasst: Montag 9. April 2012, 22:17
von MarcelF6
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!

Re: Subprocess-Modul

Verfasst: Dienstag 10. April 2012, 06:07
von 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.

Re: Subprocess-Modul

Verfasst: Dienstag 10. April 2012, 10:56
von Leonidas
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.

Re: Subprocess-Modul

Verfasst: Dienstag 10. April 2012, 11:47
von MarcelF6
@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?

Re: Subprocess-Modul

Verfasst: Dienstag 10. April 2012, 12:12
von Leonidas
Also das sys.executable ist natürlich dann kein String mehr - soweit bist du schon, oder?

Re: Subprocess-Modul

Verfasst: Dienstag 10. April 2012, 12:30
von MarcelF6
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!

Re: Subprocess-Modul

Verfasst: Dienstag 10. April 2012, 12:49
von cofi
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.

Re: Subprocess-Modul

Verfasst: Dienstag 10. April 2012, 13:53
von MarcelF6
Ah - tatsächlich. Beide Varianten funktionieren wie erwartet :)
Vielen Dank für den Hinweis!