Dokumentation in Python (Dokumentation in Python), Lektion, Seite 724012
https://www.purl.org/stefan_ram/pub/dokumentationstexte_python (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram
Python-Kurs

Dokumentation in Python 

Wir hatten am Anfang des Kurses Literale ausgewertet.

Konsoleninteraktion
"abc"
'abc'

In einer Funktionsdefinition befindliche Auswertungsanweisungen werden weiterhin ausgeführt, aber der Wert des Ausdrucks wird nicht ausgegeben, wie dies bei der Eingabe eines Ausdrucks in die Konsole geschähe.

main.py

def f():
"abc"

f()

Protokoll
(keine Ausgabe)

Ein Dokumentationstext wird normalerweise in dreifachen Anführungszeichen als erste Anweisung einer Funktion geschrieben. Es wären aber auch einfache Anführungszeichen erlaubt.

main.py
def zehnfach( x ):
"""Ergibt das Zehnfache des Argumentwerts
x -- eine Zahl
>>> zehnfach( 2 )
20
>>> zehnfach( 50 )
500
>>> zehnfach( 0 )
0
>>> zehnfach( -8 )
-80
"""
return 11 * x

Der Dokumentationstext wird bei der Erklärung der Funktion verwendet.

Protokoll
help( zehnfach )
Help on function zehnfach in module __main__:

zehnfach(x)
Ergibt das Zehnfache des Argumentwerts
x -- eine Zahl
>>> zehnfach( 2 )
20
>>> zehnfach( 50 )
500
>>> zehnfach( 0 )
0
>>> zehnfach( -8 )
-80

Wenn Beispiele in der gezeigten Schreibweise verwendet wurden, können sie automatisch für Überprüfungen der Funktion verwendet werden.

Protokoll

from doctest import testmod

testmod()

**********************************************************************
File "__main__", line 4, in __main__.zehnfach
Failed example:
zehnfach( 2 )
Expected:
20
Got:
22
**********************************************************************
File "__main__", line 6, in __main__.zehnfach
Failed example:
zehnfach( 50 )
Expected:
500
Got:
550
**********************************************************************
File "__main__", line 10, in __main__.zehnfach
Failed example:
zehnfach( -8 )
Expected:
-80
Got:
-88
**********************************************************************
1 items had failures:
3 of 4 in __main__.zehnfach
***Test Failed*** 3 failures.
TestResults(failed=3, attempted=4)

Wir zeigen im folgenden eine korrigierte Fassung der Funktionsdefinition.

Neue Funktionsdefinition
def zehnfach( x ):
"""Ergibt das Zehnfache des Argumentwerts
x -- eine Zahl
>>> zehnfach( 2 )
20
>>> zehnfach( 50 )
500
>>> zehnfach( 0 )
0
>>> zehnfach( -8 )
-80
"""
return 10 * x

Die Überprüfung ergibt dann keine Fehlermeldungen mehr.

Protokoll
testmod()
TestResults(failed=0, attempted=4)

Relevanz des Testens

Eine Python -Implementation findet oft Fehler in Funktionsdefinitionen nicht, die von Übersetzern anderer Programmiersprachen in entsprechenden Programmen gefunden werden würden.

main.py

def f():
print( l )

print( 'Hallo Welt!' )

Protokoll
Hallo Welt!

Erst durch Testen  können solche Fehler gefunden werden.

main.py

def f():
"""
>>> f()
1"""
print( l )

from doctest import testmod
testmod()

print( 'Hallo Welt!' )

Protokoll (gekürzt)

NameError: name 'l' is not defined

Hallo Welt!

In vielen anderen Programmiersprachen würde ein falscher Variablenname (oder ein unpassender Typ) oft schon beim Übersetzen eines Programmes als Fehler erkannt und gemeldet werden, ohne daß ein extra Testaufruf notwendig wird.

Daher ist es in Python  noch wichtiger als in anderen Programmiersprachen, Software zu testen.

Funktionen sind testbare Software-Einheiten. Erst durch die Zerlegung eines großen Programmes in viele kleine Funktionen  läßt sich ein großes Programm noch sinnvoll dokumentieren und testen (indem die einzelnen Funktionen dokumentiert und getestet werden, aus denen es besteht). Dies ist eine große Hilfe bei der Beherrschung großer Programme.

Testen von Werten und Ausgaben ⃗

Über die Konsolenschreibweise in Dokumentationskommentaren können sowohl Rückgabewerte als auch Ausgaben getestet werden.

main.py

def f():
"""
>>> f()
20"""
return 20

from doctest import testmod

testmod()

Protokoll
main.py

def f():
"""
>>> f()
20"""
print( 20 )

from doctest import testmod

testmod()

Protokoll

Es ist zu beachten, daß das »>>>« innerhalb des Dokumentationstextes so weit eingerückt sein muß wie die erwartete Ausgabe.

main.py

def f():
""">>> f()
20"""
print( 20 )

from doctest import testmod

testmod()

Protokoll

Expected:
20

Got:
20

Ausdrücken des Quelltextes ⃗

Geht nur bei in Python  geschriebenen Funktionen!

main.py

from inspect import getsource

def f():
print( l )

print( getsource( f ))

Protokoll

def f():

print( l )

main.py

from inspect import getsource

from doctest import testmod

print( getsource( testmod ))

Protokoll
def testmod(m=None, name=None, globs=None, verbose=None,

Quellen

Die Stilfibel für Dokumentationskommentare

Die Stilfibel PEP 257  enthält Hinweise zum Stil von Dokumentationskommentaren.

Die Stilfibel für Dokumentationskommentare PEP 257
https://www.python.org/dev/peps/pep-0257/

Übungsaufgaben

/   Refaktor

In dem folgenden Programm greifen viele Funktionen auf globale Variablen zu.

Versuchen Sie, einen Teil dieser Zugriffe (im besten Fall: alle) zu eliminieren.

main.py

import urllib.request

def setup_a_direct_connection_to_the_internet():
"""this is a hack to impede the use of any proxy"""
urllib.request.getproxies = lambda: {}
urllib.request.proxy_bypass = lambda host, proxies=None: 1

def setup_globals():
global URI; URI = 'https://example.com'
global context; context = __import__( 'ssl' )._create_unverified_context()
global headers; headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)' }
global online; online = True

def fetch_page():
global source
if online:
request = urllib.request.Request( URI, headers=headers )
html = urllib.request.urlopen( request, context=context )
source = html.read()
with open( 'cache.bin', 'wb' ) as file: file.write( source )
else:
with open( 'cache.bin', 'rb' ) as file: source = file.read()

def process_page():
global source
source = source.decode( 'utf-8' ).replace( '\t', ' ' )
print( 'source', f"{source}" )

setup_a_direct_connection_to_the_internet()
setup_globals()
fetch_page()
process_page()

Protokoll

source <!doctype html>

<html>

<head>

<title>Example Domain</title>

<meta charset="utf-8" />

<meta http-equiv="Content-type" content="text/html; charset=utf-8" />

<meta name="viewport" content="width=device-width, initial-scale=1" />

<style type="text/css">

body {

background-color: #f0f0f2;

margin: 0;

padding: 0;

font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;

}

div {

width: 600px;

margin: 5em auto;

padding: 50px;

background-color: #fff;

border-radius: 1em;

}

a:link, a:visited {

color: #38488f;

text-decoration: none;

}

@media (max-width: 700px) {

body {

background-color: #fff;

}

div {

width: auto;

margin: 0 auto;

border-radius: 0;

padding: 1em;

}

}

</style>

</head>

<body>

<div>

<h1>Example Domain</h1>

<p>This domain is established to be used for illustrative examples in documents. You may use this

domain in examples without prior coordination or asking for permission.</p>

<p><a href="http://www.iana.org/domains/example">More information...</a></p>

</div>

</body>

</html>

 

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram724012 stefan_ram:724012 Dokumentation in Python Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd724012, slrprddef724012, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/dokumentationstexte_python