Python: Reagieren Sie auf Eingabeaufforderungen
Ich versuche, Python zu verwenden, um mit einem anderen Programm über die Befehlszeile zu interagieren. Das Hauptproblem, das ich habe, ist ein spezifischer Anruf, der mehrere Follow-up-Aufforderungen hat. Zunächst fragt der Befehlszeilenaufruf nach dem Namen eines Projekts und fragt dann, ob ich einen der Unterordner des Projekts anzeigen möchte. Ich muss jedes von diesen der Reihe nach mit y / n beantworten, und die Antwort auf jedes ist leider nicht alle y oder n. Außerdem kann ich die Antwort auf die Frage nicht wissen, ohne die einzelnen Eingabeaufforderungen gelesen zu haben, sodass ich nicht in der Lage bin, einen Block mit 'y' oder 'n' auf einmal zu senden.
Dies ist der Befehlszeilenaufruf:
si viewproject
Nach der Eingabe des Befehls wird in der Befehlszeile Folgendes angezeigt:
Geben Sie den Projektnamen ein:
Und eine beispielhafte Antwort wäre:
Geben Sie den Projektnamen ein: c: /test.pj
Nach dem Eingeben des Projekts wird Folgendes angezeigt:
Möchten Sie in das Teilprojekt test_subprj.pj zurückkehren? [ynYN] (n)
An diesem Punkt muss ich entweder mit a y oder n antworten, je nachdem, ob ich das Teilprojekt benötige. Die Beantwortung dieser Frage ist wiederum vom Teilprojekt abhängig. Ich muss in der Lage sein, das Teilprojekt in dieser Eingabeaufforderung zu lesen, um darauf mit einem 'y' oder 'n' zu antworten.
Derzeit muss ich das Projekt und jedes der ys bzw. ns manuell eingeben. Mein Ziel ist es, diesen Prozess mit Python zu automatisieren.
Gibt es eine Möglichkeit, auf diese Befehlszeilenansagen automatisch zu reagieren?
Laufender FortschrittTeilprozess-Strategie project_path = "c:/test.pj"
with Popen(["si", "viewproject", "--project=" + project_path],
stdin=PIPE, stdout=PIPE, universal_newlines=True) as p:
for line in p.stdout:
if line.startswith("Do you want"):
answer = 'n'
else:
continue # skip it
print(answer, file=p.stdin) # provide answer
p.stdin.flush()
Diese Methode hängt nach der with Popen-Anweisung. Es macht niemals Fehler, aber es tritt niemals in die for-Anweisung ein oder verlässt sie und wird niemals vervollständigt. Momentan setze ich standardmäßig alle Antworten auf "n", aber das wird später durch Logik ersetzt.
Winpexpect-Strategie import re
import sys
from functools import partial
import winpexpect
project_path = "c:/test.pj"
p = winpexpect.winspawn('si viewproject --project=' + project_path)
p.logfile = sys.stdout
patterns = [re.compile('ynYN'), winpexpect.EOF]
for found in iter(partial(p.expect, patterns), 1): # until EOF
if found == 0:
answer = 'n'
p.sendline(answer)
Gibt die folgende Fehlermeldung zurück:
Traceback (most recent call last):
File "C:\Python33\lib\site-packages\winpexpect-1.5-py3.3.egg\winpexpect.py", line 541, in read_nonblocking
handle, status, data = self.child_output.get(timeout=timeout)
File "C:\Python33\lib\queue.py", line 175, in get
raise Empty
queue.Empty
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Python33\lib\site-packages\winpexpect-1.5-py3.3.egg\pexpect.py", line 1378, in expect_loop
c = self.read_nonblocking (self.maxread, timeout)
File "C:\Python33\lib\site-packages\winpexpect-1.5-py3.3.egg\winpexpect.py", line 543, in read_nonblocking
raise TIMEOUT('Timeout exceeded in read_nonblocking().')
pexpect.TIMEOUT: Timeout exceeded in read_nonblocking().
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "K:\eclipse_3.6.0\plugins\org.python.pydev_2.6.0.2012062818\pysrc\pydev_runfiles.py", line 432, in __get_module_from_str
mod = __import__(modname)
File "C:\workspace\Test_prj\Test_prj.py", line 19, in <module>
for found in iter(partial(p.expect, patterns), 1): # until EOF
File "C:\Python33\lib\site-packages\winpexpect-1.5-py3.3.egg\pexpect.py", line 1311, in expect
return self.expect_list(compiled_pattern_list, timeout, searchwindowsize)
File "C:\Python33\lib\site-packages\winpexpect-1.5-py3.3.egg\pexpect.py", line 1325, in expect_list
return self.expect_loop(searcher_re(pattern_list), timeout, searchwindowsize)
File "C:\Python33\lib\site-packages\winpexpect-1.5-py3.3.egg\pexpect.py", line 1409, in expect_loop
raise TIMEOUT (str(e) + '\n' + str(self))
pexpect.TIMEOUT: Timeout exceeded in read_nonblocking().
<winpexpect.winspawn object at 0x0144AE50>
version: 2.3 ($Revision: 399 $)
command: si
args: ['si', 'viewproject', '--project=c:/test.pj']
searcher: searcher_re:
0: re.compile("ynYN")
1: EOF
buffer (last 100 chars):
before (last 100 chars):
after: <class 'pexpect.TIMEOUT'>
match: None
match_index: None
exitstatus: None
flag_eof: False
pid: 6448
child_fd: 4
closed: False
timeout: 30
delimiter: <class 'pexpect.EOF'>
logfile: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='Cp1252'>
logfile_read: None
logfile_send: None
maxread: 2000
ignorecase: False
searchwindowsize: None
delaybeforesend: 0.05
delayafterclose: 0.1
delayafterterminate: 0.1
ERROR: Module: Test_prj could not be imported (file: C:\workspace\Test_prj\Test_prj.py).
Winpexpect installierenLazy Persons Way
Optional: Installieren Sie Nose
Optional: Installieren Sie Pip
Erste Welt Probleme
Python ist eine neue Sprache für mich, und ich hatte noch nie zuvor ein Paket für Python installiert. Darüber hinaus unterscheidet sich Python 3.x ein wenig von den anderen Python-Versionen, sodass die Installation von Modulen ein wenig abenteuerlicher ist.
Um anderen zu helfen, ein süßes, süßes Modul zu entwickeln (und denjenigen zu helfen, die besser informiert sind, um zu sehen, ob ich etwas falsch gemacht habe), folgt in Kürze eine Erfolgsgeschichte (hoffentlich), in der dokumentiert wird, wie ich mein erstes Modul erhalten und installiert habe.
Konfiguration
Mit Python können Gruppen von Drittanbietern Module entwickeln und verteilen, die die Fähigkeiten der Programmiersprache erweitern. Natürlich gibt es eine Standardmethode, mit der Entwickler von Drittanbietern dem Endbenutzer Module so einfach wie möglich zur Verfügung stellen können.
Für Python 3.x heißt dieser Standard zum Verteilen von Modulen Distutils.
So verwendet ein Entwickler Distutils:Verteilen von Python-Modulen
Und so verwendet der Endbenutzer Distutils:Python-Module installieren
Normalerweise reicht es aus, in der Befehlszeile zum Ordner Ihres heruntergeladenen Moduls zu navigieren und "setup.py install" auszuführen.
ABER
Manchmal ist das Leben nicht so einfach und Sie haben immer noch Probleme mit Ihrer Installation. Möglicherweise brauchen Sie sogar noch etwas anderes. Beispielsweise wird möglicherweise die folgende Fehlermeldung angezeigt:
"ImportError" Kein Modul namens Setuptools ""
Zum Glück gibt es dafür eine Lösung:Python 3: ImportError "Kein Modul namens Setuptools"
Wie sich herausstellt, verwendet nicht alles Distutils. Einige Pakete verwenden Setuptools. Leider gibt es für Python 3.x keine Setuptools. Python 3.x verwendet vielmehr Distribute, einen Zweig von Setuptools.
Für diejenigen, die Python 3.x verwenden, ist hier Distribute:Verteilen
Für diejenigen, die Python 2.x verwenden, ist hier Setuptools:Setuptools
In den Installationsanweisungen für Distribute heißt es: "Downloaddistribute_setup.py <http://python-distribute.org/distribute_setup.py>
_ und führen Sie es mit dem Python-Interpreter Ihrer Wahl aus. "
Außerdem heißt es: "Beachten Sie, dass diese Datei auch in der Quellversion enthalten ist."
Also habe ich Distribute heruntergeladen und auf dem Computer gespeichert. Nachdem es auf dem Computer gespeichert wurde, habe ich distribute_setup.py aus der Quellversion ausgeführt und die folgende Fehlermeldung erhalten:
Downloading http://pypi.python.org/packages/source/d/distribute/distribute-0.6.36.tar.gz
Traceback (most recent call last):
File "C:\Python33\lib\urllib\request.py", line 1252, in do_open
h.request(req.get_method(), req.selector, req.data, headers) File "C:\Python33\lib\http\client.py", line 1049, in request
self._send_request(method, url, body, headers)
File "C:\Python33\lib\http\client.py", line 1087, in _send_request
self.endheaders(body)
File "C:\Python33\lib\http\client.py", line 1045, in endheaders
self._send_output(message_body)
File "C:\Python33\lib\http\client.py", line 890, in _send_output
self.send(msg)
File "C:\Python33\lib\http\client.py", line 828, in send
self.connect()
File "C:\Python33\lib\http\client.py", line 806, in connect
self.timeout, self.source_address)
File "C:\Python33\lib\socket.py", line 406, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
socket.gaierror: [Errno 11001] getaddrinfo failed
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\workspace\PythonTest\distribute_setup.py", line 553, in <module>
sys.exit(main())
File "C:\workspace\PythonTest\distribute_setup.py", line 549, in main
tarball = download_setuptools(download_base=options.download_base)
File "C:\workspace\PythonTest\distribute_setup.py", line 204, in download_setuptools
src = urlopen(url)
File "C:\Python33\lib\urllib\request.py", line 160, in urlopen
return opener.open(url, data, timeout)
File "C:\Python33\lib\urllib\request.py", line 473, in open
response = self._open(req, data)
File "C:\Python33\lib\urllib\request.py", line 491, in _open
'_open', req)
File "C:\Python33\lib\urllib\request.py", line 451, in _call_chain
result = func(*args)
File "C:\Python33\lib\urllib\request.py", line 1272, in http_open
return self.do_open(http.client.HTTPConnection, req)
File "C:\Python33\lib\urllib\request.py", line 1255, in do_open
raise URLError(err)
urllib.error.URLError: <urlopen error [Errno 11001] getaddrinfo failed>
Na das ist doch nicht gut! Ich weiß ehrlich gesagt immer noch nicht, woher dieser Fehler kommt oder warum er passiert ist.
Egal, dann habe ich die folgende Seite gefunden, die eine .exe ausführte, um sowohl Distribute als auch Pip zu installieren.
Also habe ich diese installiert und dann die folgende Site verwendet, um meinen Computer so einzurichten, dass easy_install einfacher verwendet werden kann:Einfache Installation einrichten leicht gemacht
Sobald ich das zum Laufen gebracht habe habe ich dann die Nase eingebaut:Nase
Der Grund, warum ich Nase bekam, war, weil dieWinpexpect-Website sagt: "WinPexpect enthält Komponententests. Um die Tests auszuführen, benötigen Sie Nase. Verwenden Sie den folgenden Befehl, um die Tests auszuführen:
$ python setup.py test "
Na das hört sich ja gut an :). Jetzt wünschte ich mir nur, ich wüsste, wo ich diesen Test durchführen soll. Ich weiß, dass Sie, wenn Sie manuell installieren, den Befehl setup.py install verwenden, sodass sich auf jeden Fall eine setup.py im komprimierten Online-Verzeichnis befindet. Um zu sehen, ob dies korrekt ist, habe ich die winpexpect-Datei heruntergeladen und gespeichert, die Informationen extrahiert, über die Befehlszeile darauf zugegriffen und den setup.py-Test ausgeführt.
Hier war das folgende Ergebnis:
running test
running build_py
running egg_info
creating c:\documents and settings\slz1fh\desktop\winpexpect\geertj-winpexpect-76df3cfcb143\build\lib\winpexpect.egg-info
writing c:\documents and settings\slz1fh\desktop\winpexpect\geertj-winpexpect-76df3cfcb143\build\lib\winpexpect.egg-info\PKG-INFO
writing dependency_links to c:\documents and settings\slz1fh\desktop\winpexpect\geertj-winpexpect-76df3cfcb143\build\lib\winpexpect.egg-info\dependency_links.txt
writing top-level names to c:\documents and settings\slz1fh\desktop\winpexpect\geertj-winpexpect-76df3cfcb143\build\lib\winpexpect.egg-info\top_level.txt
writing requirements to c:\documents and settings\slz1fh\desktop\winpexpect\geertj-winpexpect-76df3cfcb143\build\lib\winpexpect.egg-info\requires.txt
writing manifest file 'c:\documents and settings\slz1fh\desktop\winpexpect\geertj-winpexpect-76df3cfcb143\build\lib\winpexpect.egg-info\SOURCES.txt'
reading manifest file 'c:\documents and settings\slz1fh\desktop\winpexpect\geertj-winpexpect-76df3cfcb143\build\lib\winpexpect.egg-info\SOURCES.txt'
writing manifest file 'c:\documents and settings\slz1fh\desktop\winpexpect\geertj-winpexpect-76df3cfcb143\build\lib\winpexpect.egg-info\SOURCES.txt'
running build_ext
Traceback (most recent call last):
File "C:\Documents and Settings\SLZ1FH\Desktop\winpexpect\geertj-winpexpect-76df3cfcb143\setup.py", line 35, in <module>
use_2to3 = True
File "C:\Python33\lib\distutils\core.py", line 148, in setup
dist.run_commands()
File "C:\Python33\lib\distutils\dist.py", line 917, in run_commands
self.run_command(cmd)
File "C:\Python33\lib\distutils\dist.py", line 936, in run_command
cmd_obj.run()
File "C:\Python33\lib\site-packages\distribute-0.6.36-py3.3.egg\setuptools\command\test.py", line 138, in run
self.with_project_on_sys_path(self.run_tests)
File "C:\Python33\lib\site-packages\distribute-0.6.36-py3.3.egg\setuptools\command\test.py", line 118, in with_project_on_sys_path
func()
File "C:\Python33\lib\site-packages\distribute-0.6.36-py3.3.egg\setuptools\command\test.py", line 164, in run_tests
testLoader = cks
File "C:\Python33\lib\unittest\main.py", line 124, in __init__
self.parseArgs(argv)
File "C:\Python33\lib\unittest\main.py", line 168, in parseArgs
self.createTests()
File "C:\Python33\lib\unittest\main.py", line 175, in createTests
self.module)
File "C:\Python33\lib\unittest\loader.py", line 137, in loadTestsFromNames
suites = [self.loadTestsFromName(name, module) for name in names]
File "C:\Python33\lib\unittest\loader.py", line 137, in <listcomp>
suites = [self.loadTestsFromName(name, module) for name in names]
File "C:\Python33\lib\unittest\loader.py", line 96, in loadTestsFromName
module = __import__('.'.join(parts_copy))
File "C:\Python33\lib\site-packages\nose-1.3.0-py3.3.egg\nose\__init__.py", line 1, in <module>
from nose.core import collector, main, run, run_exit, runmodule
File "C:\Python33\lib\site-packages\nose-1.3.0-py3.3.egg\nose\core.py", line 143
print "%s version %s" % (os.path.basename(sys.argv[0]), __version__)
^
SyntaxError: invalid syntax
Ok, also die Python 3.3-Version von Nose enthält eine ungültige Syntax für Python 3.3?
print "% s version% s"% (os.path.basename (sys.argv [0]),Ausführung) ...
sollte auf jeden Fall in Klammern stehen ... Dies lässt mich die Frage stellen, ob die Nase hier tatsächlich funktioniert, da sie offensichtlich für frühere Versionen von Python erstellt wurde.