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 installieren

Lazy Persons Way

Installieren Sie Distribute

Mach das

Installieren Sie PyWin32

Installieren Sie Winpexpect

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.

Installieren Sie Distribute

Installieren Sie Pip

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.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage