{"id":5501,"date":"2012-09-12T19:57:19","date_gmt":"2012-09-12T23:57:19","guid":{"rendered":"http:\/\/cscircles.cemc.uwaterloo.ca\/?page_id=5501"},"modified":"2020-04-08T08:39:18","modified_gmt":"2020-04-08T12:39:18","slug":"11b-de","status":"publish","type":"page","link":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/11b-de\/","title":{"rendered":"11B: Geltungsbereich von Variablen"},"content":{"rendered":"<p><em>Lektion 11 hat drei Teile A, B, C, die in beliebiger Reihenfolge ausgef\u00fchrt werden k\u00f6nnen.<\/em><\/p>\n<p>In dieser Lektion erkl\u00e4ren wir ein Konzept, das wir <em>variable scope<\/em> (etwa: Geltungsbereich von Variablen) nennen. Die wichtigste Idee ist, dass es m\u00f6glich ist, zwei <em>unterschiedliche<\/em> Variablen mit dem selben Namen zu haben, wann immer sie einen unterschiedlichen \u201escope\u201c haben. Das macht es viel einfacher, Programme zu schreiben oder zu bearbeiten, besonders gro\u00dfe.<\/p>\n<h2>Ein Beispiel f\u00fcr \u201evariable scopes\u201c<\/h2>\n<p>F\u00fcr dieses Beispiel wird ein Teil unseres Programms die folgende Funktion sein:<\/p>\n<pre>def square(x):\r\n   value = x * x\r\n   return value<\/pre>Dies ist eine Funktion, die das Quadrat der Zahl <code>x<\/code> berechnet; zum Beispiel gibt <code>square(5)<\/code> den Wert <code>25<\/code> zur\u00fcck. Aber nehmen wir jetzt einmal an, wir riefen <code>square<\/code> von einem anderen Teil des Programms auf, der au\u00dferdem auch eine <code>value<\/code> Variable f\u00fcr einen anderen Zweck verwendet:<\/p>\n<pre># Hier beginnt das Hauptprogramm\r\nvalue = 17\r\nfivesquared = square(5)\r\nprint(fivesquared, value)<\/pre>Die Frage ist, was wird in diesem Szenario ausgegeben? Es gibt zwei M\u00f6glichkeiten, wenn wir nicht wissen, wie Python funktioniert:<\/p>\n<ol>\n<li>Eine M\u00f6glichkeit ist, dass Python erkennt, dass die zwei <code>value<\/code> Variablen irgendwie \u201eauseinandergehalten\u201c werden. Der Aufruf von <code>square<\/code> wird 25 liefern, aber der Wert von <code>value<\/code> im Hauptprogramm wird bei 17 bleiben, und wir sehen den Output <code>25<\/code> <code>17<\/code>.<\/li>\n<li>Die andere M\u00f6glichkeit ist, dass, wenn <code>square<\/code> ausgef\u00fchrt wird, es den Wert von <code>value<\/code> mit 25 \u00fcberschreibt, und wir sehen den Output <code>25<\/code> <code>25<\/code>.<\/li>\n<\/ol>\n<p>Lass uns sehen, was tats\u00e4chlich passiert!<\/p>\n<p><iframe width='100%' height='480' frameborder='0' scrolling='no' src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/OnlinePythonTutor3-cemc\/iframe-embed.html#code=def+square%28x%29%3A%0A++++value+%3D+x+%2A+x%0A++++return+value%0A%0A%23+main+body+of+the+program+starts+here%0Avalue+%3D+17%0Afivesquared+%3D+square%285%29%0Aprint%28fivesquared%2C+value%29&cumulative=false&heapPrimitives=false&drawParentPointers=false&textReferences=false&showOnlyOutputs=false&py=3&curInstr=0&resizeContainer=true&highlightLines&width=450&rightStdout=1'><\/iframe><\/p>\n<p>Wir sehen, dass Pythons Verhalten konsistent ist mit M\u00f6glichkeit #1. Tats\u00e4chlich ist es so, dass, <em>wann immer du eine Funktion aufrufst, du keine Variablen beeinflussen kannst, die au\u00dferhalb der Funktion definiert sind.<\/em> Statt dessen ist es so, dass jedes Statement, das Variablen Werte zuweist, nur eine \u201elokale\u201c (d.h. \u00f6rtliche) Variable beeinflusst, die sich \u201eim\u201c Funktionsaufruf befindet. Der <strong>Grund<\/strong> daf\u00fcr, dass Python und die meisten anderen Sprachen so funktionieren: So ist es viel einfacher, lange Programme mit einer Vielzahl an Funktionen zu schreiben. Wenn wir eine neue Funktion definieren, k\u00f6nnen wir in der Funktion beliebige Variablennamen verwenden (inklusive von h\u00e4ufigen Namen wie <code>result,<\/code><code>temp<\/code> und <code>i<\/code>), selbst wenn sie anderswo aus anderen Gr\u00fcnden benutzt werden.<\/p>\n<p>Um dies im Detail zu sehen, siehe dir \"Schritt 6 von 8\" im Visualisierer an. Beachte, dass es dort zwei verschiedene <code>value<\/code> Variablen gibt: eine in der <code>square<\/code> Funktion und eine au\u00dferhalb (im \"globalen\" Bereich).<br \/>\n<!--\n\n\n<h2>Illustration<\/h2>\n\n\nUm dies klarer zu machen, geben wir dir eine Tabelle, die darstellt, wie sich die Werte \u00e4ndern.\n\n\n<table style=\"margin-bottom: 0px; padding-right: 15px;\">\n\n<colgroup> \n\n<col width=\"30%\" \/> <\/colgroup>\n\n \n\n<colgroup> \n\n<col width=\"12%\" \/> \n\n<col width=\"12%\" \/> \n\n<col width=\"16%\" \/> \n\n<col width=\"14%\" \/> \n\n<col width=\"16%\" \/> <\/colgroup>\n\n\n\n\n<tbody>\n\n\n<tr>\n\n\n<th>Nach diesem Befehl:<\/th>\n\n\n\n\n<th colspan=\"3\" style=\"text-align: center;\">globale Werte<\/th>\n\n\n\n\n<th colspan=\"2\" style=\"text-align: center;\">lokale Werte in <code>square(5)<\/code><\/th>\n\n\n<\/tr>\n\n\n\n\n<tr>\n\n\n<th><\/th>\n\n\n\n\n<th style=\"text-align: center;\"><code>square<\/code><\/th>\n\n\n\n\n<th style=\"text-align: center;\"><code>value<\/code><\/th>\n\n\n\n\n<th style=\"text-align: center;\"><code>fivesquared<\/code><\/th>\n\n\n\n\n<th style=\"text-align: center;\"><code>x<\/code><\/th>\n\n\n\n\n<th style=\"text-align: center;\"><code>value<\/code><\/th>\n\n\n<\/tr>\n\n\n<\/tbody>\n\n\n<\/table>\n\n\n\n\n<div id=\"foo\" style=\"margin-top: 0px; overflow-y: scroll; max-height: 100px;\">\n\n\n<table style=\"font-family: monospace; font-size: 12px; margin-bottom: 5px;\">\n\n<colgroup> \n\n<col width=\"30%\" \/> <\/colgroup>\n\n \n\n<colgroup> \n\n<col width=\"12%\" \/> \n\n<col width=\"12%\" \/> \n\n<col width=\"16%\" \/> \n\n<col width=\"14%\" \/> \n\n<col width=\"16%\" \/> <\/colgroup>\n\n\n\n\n<tbody>\n\n\n<tr>\n\n\n<td>def square(x): \u00ab+2 more lines\u00bb<\/td>\n\n\n\n\n<td style=\"text-align: center;\"><strong>\u00abfnc obj\u00bb<\/strong><\/td>\n\n\n\n\n<td><\/td>\n\n\n\n\n<td><\/td>\n\n\n\n\n<td><\/td>\n\n\n\n\n<td><\/td>\n\n\n<\/tr>\n\n\n\n\n<tr>\n\n\n<td>value = 17<\/td>\n\n\n\n\n<td style=\"text-align: center;\">\u00abfnc obj\u00bb<\/td>\n\n\n\n\n<td style=\"text-align: center;\"><strong>17<\/strong><\/td>\n\n\n\n\n<td><\/td>\n\n\n\n\n<td><\/td>\n\n\n\n\n<td><\/td>\n\n\n<\/tr>\n\n\n\n\n<tr>\n\n\n<td>\u00abcall square(5)\u00bb<\/td>\n\n\n\n\n<td style=\"text-align: center;\">\u00abfnc obj\u00bb<\/td>\n\n\n\n\n<td style=\"text-align: center;\">17<\/td>\n\n\n\n\n<td><\/td>\n\n\n\n\n<td style=\"text-align: center;\"><strong>5<\/strong><\/td>\n\n\n\n\n<td><\/td>\n\n\n<\/tr>\n\n\n\n\n<tr>\n\n\n<td><span style=\"color: white;\">---<\/span>value = x * x<\/td>\n\n\n\n\n<td style=\"text-align: center;\">\u00abfnc obj\u00bb<\/td>\n\n\n\n\n<td style=\"text-align: center;\">17<\/td>\n\n\n\n\n<td><\/td>\n\n\n\n\n<td style=\"text-align: center;\">5<\/td>\n\n\n\n\n<td style=\"text-align: center;\"><strong>25<\/strong><\/td>\n\n\n<\/tr>\n\n\n\n\n<tr>\n\n\n<td><span style=\"color: white;\">---<\/span>return value<\/td>\n\n\n\n\n<td style=\"text-align: center;\">\u00abfnc obj\u00bb<\/td>\n\n\n\n\n<td style=\"text-align: center;\">17<\/td>\n\n\n\n\n<td style=\"text-align: center;\">25<\/td>\n\n\n\n\n<td style=\"text-align: center;\">5<\/td>\n\n\n\n\n<td style=\"text-align: center;\">25<\/td>\n\n\n<\/tr>\n\n\n\n\n<tr>\n\n\n<td>print(fivesquared, value)<\/td>\n\n\n\n\n<td style=\"text-align: center;\">\u00abfnc obj\u00bb<\/td>\n\n\n\n\n<td style=\"text-align: center;\">17<\/td>\n\n\n\n\n<td style=\"text-align: center;\">25<\/td>\n\n\n\n\n<td><\/td>\n\n\n\n\n<td><\/td>\n\n\n<\/tr>\n\n\n<\/tbody>\n\n\n<\/table>\n\n\n<\/div>\n\n\nIn dieser Tabelle illustrieren wir drei neue Details.\n\n\n<ul>\n\t\n\n<li>Der lokale Bereich verschwindet, nachdem das Aufrufen der Funktion beendet ist.<\/li>\n\n\n\t\n\n<li>Die Weise, in der wir eine Funktion auf ihre Argumente anwenden, ist, indem wir lokale Variablen verwenden! Wenn wir <code>square(5)<\/code> aufrufen, ist dies das gleiche, als ob wir einen neuen lokalen Bereich schaffen w\u00fcrden, indem wir eine Variable <code>x<\/code> mit dem Wert <code>5<\/code> zum lokalen Bereich hinzuf\u00fcgen und dann die Befehle der Funktion im lokalen Bereich ausf\u00fchren.<\/li>\n\n\n\t\n\n<li>(Der dritte Fakt ist nicht bezogen auf Bereiche, aber ist hilfreich zu wissen:) Die Definition der Funktion <code>square<\/code> wird von Python tats\u00e4chlich folgenderma\u00dfen ausgef\u00fchrt: ein neues Funktionsobjekt <code>\u00abfnc obj\u00bb<\/code> wird definiert, dann wird eine Variable <code>square<\/code> so definiert, dass sie gleich dem Objekt ist. Funktionen sind also spezielle Variablen.<\/li>\n\n\n<\/ul>\n\n\nWie \u00fcblich k\u00f6nnte es interessant sein zu sehen, wie dies im <a href=\"\/visualize\">Visualization Tool<\/a> aussieht.--><\/p>\n<div class='pybox modeNeutral' id='pybox0'>\n<img title='You have not yet completed this problem.' src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/files\/icon.png' class='pycheck'\/><div class=\"heading\"><span class='type'>Multiple Choice Exercise: <\/span><span class='title'>Inner and Outer<\/span><\/div><div>Was ist die Ausgabe des folgenden Programms?<\/p>\n<pre>x = \"outer\"\r\ndef xReplace(value):\r\n   x = value\r\nxReplace(\"inner\")\r\nprint(x)<\/pre><\/div><label>Your choice: <\/label><select id=\"pyselect0\"><option value=\"d\" selected>Select one<\/option><option value=\"w\">inner<\/option><option value=\"w\">Das Programm erzeugt einen Fehler.<\/option><option value=\"r\">outer<\/option><\/select><div class='pyboxbuttons'><input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" name=\"slug\" value=\"11b.inout\"\/><input type='submit' style='margin:5px;' value='Check answer' onClick='pbMultiCheck(0)'\/><\/div><div class=\"pbresults\" id=\"pyMultiResults0\"><\/div><div class=\"epilogue\">Korrekt! Das Statement <code>x = value<\/code> betrifft nur die \u00f6rtliche Version der Variable <code>x<\/code> innerhalb der Funktion. Die globale Version von <code>x<\/code> ver\u00e4ndert sich nicht. (also ist die Funktion <code>xReplace<\/code> nutzlos und hat niemals einen Effekt.)<\/div><\/div>\n<p>Ein \u00e4hnliches Konzept wie <em>scope<\/em> ist <em>namespace<\/em>. Ein Namespace ist sowas wie ein Bereich f\u00fcr ein Modul. Also auch wenn du ein ganzes Modul <code>import<\/code>ierst (wie z.B. <code>math<\/code>), das den Variablennamen <code>x<\/code> irgendwo verwendet, \u00fcberschneidet es sich nicht mit der Variable <code>x<\/code>, die von deinem Programm benutzt wird, da sie in unterschiedlichen Namespaces liegen.<\/p>\n<h2>Scoping Regeln: Hinausblicken<\/h2>\n<p>Es gibt Situationen, bei denen wir Variablen von lokalen und globalen Bereichen vermischen m\u00f6chten. Ein \u00fcbliches Beispiel ist, dass wir eine gemeinsame Variable am Anfang des Programms initialisiert haben und au\u00dferdem m\u00f6chten, dass Funktionen in der Lage sind, die Variable zu lesen.<\/p>\n<p><form class=\"pbform\" action=\"#\" id=\"pbform1\" method=\"POST\">\n<div class='pybox modeNeutral  facultative' id='pybox1'>\n<div class=\"heading\"><span class=\"title\">Example<\/span><\/div>Eine globale Variable von innerhalb einer Funktion auslesen<div class='pyboxTextwrap pyboxCodewrap RO '  style='height: 110px;'><textarea wrap='off' name='usercode1' id='usercode1'  cols=10 rows=4 readonly='readonly'  style = 'height : 110px;'  class='pyboxCode RO'>\nfavouriteTopping='pepperoni'\ndef orderPizzas(n):\n print(\"I'd like\", str(n), favouriteTopping, \"pizzas\")\norderPizzas(3)<\/textarea><\/div>\n<div id='pbhistory1' class='flexcontain' style='display:none;'><\/div>\n<div class='pyboxbuttons'><table><tr>\n<td><input type='submit' name='submit' id='submit1' value=' '\/><\/td>\n<td><input type='button' name='consolecopy' value=\"Open in console\" onclick=\"pbConsoleCopy(1)\" ><\/td>\n<td><input type='button' name='visualize' value=\"Visualize\" onclick=\"pbVisualize(1,'N')\" ><\/td>\n<\/tr><\/table><\/div>\n<input type=\"hidden\" name=\"lang\" value=\"\"\/><input type=\"hidden\" id=\"inputInUse1\" name=\"inputInUse\" value=\"Y\"\/>\n<input type=\"hidden\" name=\"pyId\" value=\"1\"\/>\n<input type=\"hidden\" name=\"hash\" value=\"6283e6e1d383f13a78a4aaa39e5b6aad\"\/>\n<div id='pbresults1' class='pbresults'><\/div>\n<\/div>\n<\/form>\n<script type='text\/javascript'>document.getElementById(\"submit1\").value = \"Run program\";document.getElementById(\"inputInUse1\").value = \"N\";<\/script>\n<\/p>\n<p>Hier beinhaltet der lokale Bereich keine Variable, die <code>favouriteTopping<\/code> genannt ist, <em>aber dies hatte keinen Fehler zur Folge<\/em>. Pythons Regel f\u00fcr die Auswertung von Variablen ist: Wird eine Variable ausgewertet, die nicht im lokalen Bereich existiert, dann sucht Python sie im globalen Bereich. In unserem Fall wurde <code>favouriteTopping<\/code> tats\u00e4chlich im globalen Bereich gefunden. (In einem allgemeineren Fall mit dem K\u00f6rper einer Funktion, der eine andere Funktion aufruft, w\u00fcrdest du drei Bereiche haben; Python sucht eine Variable zuerst im \u201elokalsten\u201c Bereich und arbeitet sich dann Schritt f\u00fcr Schritt zum globalen Bereich vor, bis die Variable gefunden wird.)<\/p>\n<p><table class='pywarn'><tr><td class='pywarnleft'><img src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/files\/warning.png'\/><\/td><td class='pywarnright'><span> Zwei der Beispiele oben, mit <code>orderPizzas<\/code> und <code>xReplace<\/code>, sind syntaktisch fast identisch. Warum erzeugt Python eine neue lokale Variable <code>x<\/code> in <code>xReplace<\/code>, aber keine neue <code>favouriteTopping<\/code> in <code>orderPizzas<\/code>? Pythons Regel ist die folgende: wenn man die Variable nur ausliest, dann wird keine neue lokale Variable erzeugt; aber sobald man der Variable einen neuen Wert gibt, dann wird sie im <em>gesamten<\/em> Funktionsk\u00f6rper als lokale Variable behandelt. (Das ist der \u00fcblichste Grund f\u00fcr <a href=\"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/console\/?consolecode=x%20%3D%201%0Adef%20f%28%29%3A%0A%20%20%20print%28x%29%0A%20%20%20x%20%3D%202%0Af%28%29\" target=\"_blank\"><code>UnboundLocalError<\/code><\/a>: lies dazu diese zwei Fragen [<a href=\"http:\/\/docs.python.org\/py3k\/faq\/programming.html#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value\" target=\"_blank\" rel=\"noopener noreferrer\">1<\/a>, <a href=\"http:\/\/docs.python.org\/py3k\/faq\/programming.html#what-are-the-rules-for-local-and-global-variables-in-python\" target=\"_blank\" rel=\"noopener noreferrer\">2<\/a>] in der offiziellen Python-Dokumentation.) <\/span><\/td><\/table><\/p>\n<p>Funktionsargumente werden <em>immer<\/em> als neue lokale Variablen behandelt, wie es das folgende nicht funktionierte Codefragment illustriert (es versucht die Variable\u00a0<code>g<\/code>\u00a0auf\u00a0<code>0<\/code> zu setzen, aber es versagt).<\/p>\n<p><iframe width='100%' height='480' frameborder='0' scrolling='no' src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/OnlinePythonTutor3-cemc\/iframe-embed.html#code=def+resetToZero%28var%29%3A%0A+var+%3D+0%0Ag+%3D+15%0AresetToZero%28g%29%0Aprint%28g%29&cumulative=false&heapPrimitives=false&drawParentPointers=false&textReferences=false&showOnlyOutputs=false&py=3&curInstr=0&resizeContainer=true&highlightLines&width=400&rightStdout=1'><\/iframe><\/p>\n<h2><code>Globale <\/code>\u00c4nderungen<\/h2>\n<p>Wie viele andere Dinge, funktioniert der normale Ablauf wie oben beschrieben f\u00fcr 99% aller Situationen. Aber in den \u00fcbrigen 1% willst du vielleicht wirklich innerhalb einer Funktion eine globale Variable \u00e4ndern. Das geht mit Python, indem du das <code>global<\/code> Statement verwendest.<\/p>\n<p>Hier ist eine Modifikation des fr\u00fcheren <code>xReplace<\/code> Beispiels; indem die Variable in einer Funktion als <code>global<\/code> deklariert wird, kannst du die globale Variable innerhalb der Funktion \u00e4ndern.<\/p>\n<p><iframe width='100%' height='480' frameborder='0' scrolling='no' src='https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-content\/plugins\/pybox\/OnlinePythonTutor3-cemc\/iframe-embed.html#code=def+xReplace%28value%29%3A%0A++++global+x%0A++++x+%3D+value%0A%0Ax+%3D+%22outer%22%0AxReplace%28%22inner%22%29+%0Aprint%28x%29+++++++%23+%27inner%27+now%21&cumulative=false&heapPrimitives=false&drawParentPointers=false&textReferences=false&showOnlyOutputs=false&py=3&curInstr=0&resizeContainer=true&highlightLines&width=400&rightStdout=1'><\/iframe><\/p>\n<p>Wie wir fr\u00fcher erw\u00e4hnten, braucht man nicht die <code>global<\/code> Angabe um eine globale Variable zu <em>lesen<\/em>, nur um zu <em>\u00e4ndern<\/em>. Du hast nun diese Lektion beendet und kannst zur n\u00e4chsten gehen.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Lektion 11 hat drei Teile A, B, C, die in beliebiger Reihenfolge ausgef\u00fchrt werden k\u00f6nnen. In dieser Lektion erkl\u00e4ren wir ein Konzept, das wir variable scope (etwa: Geltungsbereich von Variablen) nennen. Die wichtigste Idee ist, dass es m\u00f6glich ist, zwei &hellip; <a href=\"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/11b-de\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2653,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-5501","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages\/5501","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/users\/2653"}],"replies":[{"embeddable":true,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/comments?post=5501"}],"version-history":[{"count":36,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages\/5501\/revisions"}],"predecessor-version":[{"id":11312,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages\/5501\/revisions\/11312"}],"wp:attachment":[{"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/media?parent=5501"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}