Heim  >  Artikel  >  Backend-Entwicklung  >  Entwicklertools, die Python-Programmierer kennen müssen

Entwicklertools, die Python-Programmierer kennen müssen

巴扎黑
巴扎黑Original
2017-04-08 10:34:561772Durchsuche

Python hat ein umfangreiches Ökosystem entwickelt, das das Leben von Python-Programmierern einfacher machen und ihnen die Arbeit, das Rad neu zu erfinden, erleichtern kann. Das gleiche Konzept gilt für die Arbeit von Tool-Entwicklern, auch wenn die von ihnen entwickelten Tools nicht im endgültigen Programm erscheinen. In diesem Artikel werden die Entwicklertools vorgestellt, die Python-Programmierer kennen müssen.

Für Entwickler besteht die praktischste Hilfe darin, ihnen beim Schreiben von Codedokumenten zu helfen. Das Modul pydoc kann eine gut formatierte Dokumentation für jedes importierbare Modul basierend auf Dokumentzeichenfolgen im Quellcode generieren. Python enthält zwei Test-Frameworks, um Code automatisch zu testen und die Richtigkeit des Codes zu überprüfen: 1) doctest-Modul, das Tests aus Quellcode oder eigenständigen Dateibeispielen für Anwendungsfälle extrahieren kann. 2) unittest Modul, dieses Modul ist ein automatisiertes Testframework mit vollem Funktionsumfang, das Testvorrichtungen, vordefinierte Testsuiten und Testerkennungsunterstützung bereitstellt.

Das Modul trace kann die Art und Weise überwachen, wie Python das Programm ausführt, und einen Bericht erstellen, der anzeigt, wie oft jede Zeile des Programms ausgeführt wird. Diese Informationen können verwendet werden, um Programmausführungspfade zu ermitteln, die nicht von automatisierten Testsätzen abgedeckt werden, und können auch zur Untersuchung von Programmaufrufdiagrammen verwendet werden, um Abhängigkeiten zwischen Modulen zu ermitteln. Das Schreiben und Ausführen von Tests kann in den meisten Programmen das Debuggen erleichtern, da Python in den meisten Fällen nicht behandelte Fehler an die Konsole ausgeben kann. Die Informationen werden als Traceback bezeichnet. Wenn das Programm nicht in einer Textkonsole ausgeführt wird, kann Traceback Fehlerinformationen auch in eine Protokolldatei oder ein Meldungsdialogfeld ausgeben. Wenn der Standard-Traceback nicht genügend Informationen bereitstellen kann, können Sie das Modul cgitb verwenden, um detaillierte Informationen im Stapel- und Quellcodekontext auf allen Ebenen anzuzeigen, z. B. lokale Variablen. Das Modul cgitb kann diese Tracking-Informationen auch in Form von HTML ausgeben, um Fehler in Webanwendungen zu melden.

Sobald Sie herausgefunden haben, wo das Problem liegt, müssen Sie den interaktiven Debugger verwenden, um den zu debuggenden Code einzugeben. Das pdb-Modul kann diese Aufgabe gut erledigen. Dieses Modul kann den Ausführungspfad des Programms anzeigen, wenn ein Fehler auftritt, und kann Objekte und Code zum Debuggen dynamisch anpassen. Sobald das Programm getestet und debuggt wurde, besteht der nächste Schritt darin, Ihre Aufmerksamkeit auf die Leistung zu richten. Entwickler können die Module profile und timit verwenden, um die Geschwindigkeit des Programms zu testen, herauszufinden, was im Programm langsam ist, und Beheben Sie dann das Problem. Dieser Teil des Codes wird unabhängig für die Optimierung optimiert. Python-Programme werden über einen Interpreter ausgeführt und die Eingabe in den Interpreter ist eine kompilierte Bytecode-Version des Originalprogramms. Diese kompilierte Bytecode-Version kann dynamisch generiert werden, wenn das Programm ausgeführt wird, oder sie kann generiert werden, wenn das Programm gepackt wird. Das Modul compileall kann Programmpakete verarbeiten. Es stellt paketbezogene Schnittstellen bereit, die von Installationsprogrammen und Pakettools zum Generieren von Dateien mit Modulbytecodes verwendet werden können. Gleichzeitig kann in der Entwicklungsumgebung das Modul „compileall“ auch verwendet werden, um zu überprüfen, ob die Quelldatei Syntaxfehler enthält.

Auf Quellcodeebene stellt das Modul pyclbr einen Klassenviewer bereit, der Texteditoren oder anderen Programmen das Scannen interessanter Zeichen in Python-Programmen wie Funktionen oder Klassen erleichtert. Nach der Bereitstellung eines Klassen-Viewers muss kein Code mehr eingeführt werden, wodurch mögliche Nebenwirkungen vermieden werden.

Dokumentzeichenfolgen und doctest Modul

Wenn die erste Zeile einer Funktion, Klasse oder eines Moduls eine Zeichenfolge ist, ist die Zeichenfolge eine Dokumentzeichenfolge. Es kann als gute Programmierpraxis angesehen werden, Dokumentzeichenfolgen einzuschließen, da diese Zeichenfolgen einige Informationen für Python-Programmentwicklungstools bereitstellen können. Beispielsweise kann der Befehl help() Dokumentzeichenfolgen erkennen, und auch Python-bezogene IDEs können Dokumentzeichenfolgen erkennen. Da Programmierer dazu neigen, Dokumentzeichenfolgen in einer interaktiven Shell anzuzeigen, ist es am besten, diese Zeichenfolgen kurz zu halten. Zum Beispiel

# mult.py
class Test:
    """
    >>> a=Test(5)
    >>> a.multiply_by_2()
    10
    """
    def __init__(self, number):
        self._number=number

    def multiply_by_2(self):
        return self._number*2

Beim Schreiben von Dokumentationen besteht ein häufiges Problem darin, die Dokumentation und den eigentlichen Code synchron zu halten. Beispielsweise könnte ein Programmierer die Implementierung einer Funktion ändern, aber vergessen, die Dokumentation zu aktualisieren. Um dieses Problem zu lösen, können wir das Modul doctest verwenden. Das Doctest-Modul sammelt Dokumentzeichenfolgen, scannt sie und führt sie als Tests aus. Um das Doctest-Modul verwenden zu können, erstellen wir normalerweise ein neues unabhängiges Modul zum Testen. Wenn beispielsweise das vorherige Beispiel Testklasse in der Datei mult.py enthalten ist, sollten Sie zum Testen eine neue Datei testmult.py erstellen folgt Anzeige:

# testmult.py

import mult, doctest

doctest.testmod(mult, verbose=True)

# Trying:
#     a=Test(5)
# Expecting nothing
# ok
# Trying:
#     a.multiply_by_2()
# Expecting:
#     10
# ok
# 3 items had no tests:
#     mult
#     mult.Test.__init__
#     mult.Test.multiply_by_2
# 1 items passed all tests:
#    2 tests in mult.Test
# 2 tests in 4 items.
# 2 passed and 0 failed.
# Test passed.

In diesem Code führt doctest.testmod(module) den Test eines bestimmten Moduls aus und gibt die Anzahl der fehlgeschlagenen Tests und die Gesamtzahl der Tests zurück. Wenn alle Tests erfolgreich sind, wird keine Ausgabe erzeugt. Andernfalls wird ein Fehlerbericht angezeigt, der die Differenz zwischen den erwarteten und den tatsächlichen Werten anzeigt. Wenn Sie eine detaillierte Ausgabe des Tests sehen möchten, können Sie testmod(module, verbose=True) verwenden.

Wenn Sie keine separate Testdatei erstellen möchten, können Sie auch den entsprechenden Testcode am Ende der Datei einfügen:

if __name__ == '__main__':
    import doctest
    doctest.testmod()

Wenn wir diese Art von Test durchführen möchten, können wir das Modul doctest mit der Option -m aufrufen. Normalerweise erfolgt bei der Ausführung von Tests keine Ausgabe. Wenn Sie detaillierte Informationen sehen möchten, können Sie die Option -v hinzufügen.

$ python -m doctest -v mult.py

Unit-Tests und unittest Modul

Wenn wir das Programm gründlicher testen möchten, können wir das Modul unittest verwenden. Durch Komponententests können Entwickler eine Reihe unabhängiger Testfälle für jedes Element schreiben, aus dem das Programm besteht (z. B. unabhängige Funktionen, Methoden, Klassen und Module). Beim Testen größerer Programme können diese Tests als Bausteine ​​zur Überprüfung der Korrektheit des Programms dienen. Wenn unsere Programme größer werden, können Unit-Tests für verschiedene Komponenten zu größeren Test-Frameworks und Test-Tools kombiniert werden. Dies kann die Arbeit beim Softwaretesten erheblich vereinfachen und das Auffinden und Lösen von Softwareproblemen erleichtern.

# splitter.py
import unittest

def split(line, types=None, delimiter=None):
    """Splits a line of text and optionally performs type conversion.
    ...
    """
    fields = line.split(delimiter)
    if types:
        fields = [ ty(val) for ty,val in zip(types,fields) ]
    return fields

class TestSplitFunction(unittest.TestCase):
    def setUp(self):
        # Perform set up actions (if any)
        pass
    def tearDown(self):
        # Perform clean-up actions (if any)
        pass
    def testsimplestring(self):
        r = split('GOOG 100 490.50')
        self.assertEqual(r,['GOOG','100','490.50'])
    def testtypeconvert(self):
        r = split('GOOG 100 490.50',[str, int, float])
        self.assertEqual(r,['GOOG', 100, 490.5])
    def testdelimiter(self):
        r = split('GOOG,100,490.50',delimiter=',')
        self.assertEqual(r,['GOOG','100','490.50'])

# Run the unittests
if __name__ == '__main__':
    unittest.main()

#...
#----------------------------------------------------------------------
#Ran 3 tests in 0.001s

#OK

Wenn wir Unit-Tests verwenden, müssen wir eine Klasse definieren, die von unittest.TestCase erbt. In dieser Klasse wird jeder Test in Form einer Methode definiert und mit test beginnend benannt – zum Beispiel „testsimplestring“, „testtypeconvert“ und ähnliches Benennen von Methoden (es muss betont werden, dass es in Ordnung ist, solange der Methodenname mit test beginnt, egal wie Sie ihn benennen). Innerhalb jedes Tests können Behauptungen verwendet werden, um auf unterschiedliche Bedingungen zu prüfen.

Praxisbeispiel:

Angenommen, Sie haben eine Methode in Ihrem Programm und die Ausgabe dieser Methode verweist auf die Standardausgabe (sys.stdout). Dabei handelt es sich in der Regel um die Ausgabe von Textinformationen auf dem Bildschirm. Wenn Sie Ihren Code testen möchten, um dies zu beweisen, geben Sie einfach die entsprechende Eingabe ein und die entsprechende Ausgabe wird angezeigt.

# url.py

def urlprint(protocol, host, domain):
    url = '{}://{}.{}'.format(protocol, host, domain)
    print(url)

Die integrierte Druckfunktion sendet die Ausgabe standardmäßig an sys.stdout. Um zu testen, ob die Ausgabe tatsächlich angekommen ist, können Sie sie mithilfe eines Ersatzobjekts simulieren und Aussagen über die erwarteten Werte des Programms treffen. Die Methode patch() im Modul unittest.mock kann das Objekt nur im Kontext der Testausführung ersetzen und den ursprünglichen Zustand des Objekts unmittelbar nach Abschluss des Tests zurückgeben . Das Folgende ist der Testcode für die Methode urlprint():

#urltest.py

from io import StringIO
from unittest import TestCase
from unittest.mock import patch
import url

class TestURLPrint(TestCase):
    def test_url_gets_to_stdout(self):
        protocol = 'http'
        host = 'www'
        domain = 'example.com'
        expected_url = '{}://{}.{}\n'.format(protocol, host, domain)

        with patch('sys.stdout', new=StringIO()) as fake_out:
            url.urlprint(protocol, host, domain)
            self.assertEqual(fake_out.getvalue(), expected_url)

  urlprint()函数有三个参数,测试代码首先给每个参数赋了一个假值。变量expected_url包含了期望的输出字符串。为了能够执行测试,我们使用了unittest.mock.patch()方法作为上下文管理器,把标准输出sys.stdout替换为了StringIO对象,这样发送的标准输出的内容就会被StringIO对象所接收。变量fake_out就是在这一过程中所创建出的模拟对象,该对象能够在with所处的代码块中所使用,来进行一系列的测试检查。当with语句完成时,patch方法能够将所有的东西都复原到测试执行之前的状态,就好像测试没有执行一样,而这无需任何额外的工作。但对于某些Python的C扩展来讲,这个例子却显得毫无意义,这是因为这些C扩展程序绕过了sys.stdout的设置,直接将输出发送到了标准输出上。这个例子仅适用于纯Python代码的程序(如果你想捕获到类似C扩展的输入输出,那么你可以通过打开一个临时文件然后将标准输出重定向到该文件的技巧来进行实现)。

Das obige ist der detaillierte Inhalt vonEntwicklertools, die Python-Programmierer kennen müssen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn