{"id":9977,"date":"2017-05-18T02:08:58","date_gmt":"2017-05-18T06:08:58","guid":{"rendered":"https:\/\/cscircles.cemc.uwaterloo.ca\/?page_id=9977"},"modified":"2017-07-03T17:07:18","modified_gmt":"2017-07-03T21:07:18","slug":"11b-pl","status":"publish","type":"page","link":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/11b-pl\/","title":{"rendered":"11B: Zakres Zmiennej"},"content":{"rendered":"<!-- Please retain this notice and add more notes if you create a new version.<br \/>\nOriginal lesson author: David Pritchard, daveagp@gmail.com, http:\/\/cscircles.ca<br \/>\nLicense: http:\/\/creativecommons.org\/licenses\/by-nc-sa\/3.0\/-->\n<p><em>Lekcja 11 sk\u0142ada si\u0119 z trzech cz\u0119\u015bci A, B, C, kt\u00f3re mo\u017cesz wykona\u0107 w dowolnej kolejno\u015bci.<\/em><\/p>\n<p>W tej lekcji wyja\u015bnimy poj\u0119cie <em>zakresu zmiennej<\/em>. G\u0142\u00f3wn\u0105 ide\u0105 to, \u017ce mog\u0105 istnie\u0107 dwie <em>r\u00f3\u017cne<\/em> zmienne <em>o tej samej<\/em> nazwie, gdy maj\u0105 r\u00f3\u017cne zakresy. To znacznie u\u0142atwia pisanie i edytowanie program\u00f3w, zw\u0142aszcza du\u017cych. B\u0119dzie to r\u00f3wnie\u017c niezb\u0119dnym elementem w p\u00f3\u017aniejszym temacie, rekursji<\/p>\n<h2>Przyk\u0142ad zakresu zmiennej<\/h2>\n<p>W tym przyk\u0142adzie cz\u0119\u015b\u0107 naszego programu b\u0119dzie nast\u0119puj\u0105ca:<\/p>\n<pre>def square(x):\r\n   value = x * x\r\n   return value<\/pre>Jest to funkcja, kt\u00f3ra oblicza kwadrat liczby <code>x<\/code>, na przyk\u0142ad <code>square(5)<\/code> zwraca <code>25<\/code>. Za\u0142\u00f3\u017cmy, \u017ce u\u017cyjemy nazwy <code>square<\/code> w innej cz\u0119\u015bci programu, kt\u00f3ra r\u00f3wnie\u017c wykorzystuje <code>warto\u015bci<\/code> zmiennej do innego celu:<\/p>\n<pre># g\u0142\u00f3wne cia\u0142o programu zaczyna si\u0119 tutaj\r\nvalue = 17\r\nfivesquared = square(5)\r\nprint(fivesquared, value)<\/pre>Pytanie brzmi, co zostanie wydrukowane w tym scenariuszu? Je\u015bli nie wiemy jak dzia\u0142a Python, to widzimy dwie mo\u017cliwo\u015bci:<\/p>\n<ol>\n<li>Jedn\u0105 z mo\u017cliwo\u015bci jest to, \u017ce Python uzna, \u017ce obie <code>warto\u015bci<\/code> zmiennych w jaki\u015b spos\u00f3b powinny by\u0107 \"zachowane oddzielnie\". Tak wi\u0119c wywo\u0142anie <code>square<\/code> zwr\u00f3ci 25, ale <code>warto\u015b\u0107<\/code> w g\u0142\u00f3wnym ciele b\u0119dzie nadal wynosi\u0107 17 i na wyj\u015bciu otrzymamy <code>25 <\/code><code>17<\/code>.<\/li>\n<li>Inna mo\u017cliwo\u015b\u0107 mo\u017ce by\u0107 nast\u0119puj\u0105ca, gdy wykonywany jest <code>square<\/code>, istniej\u0105ca warto\u015b\u0107 zmiennej zostanie nadpisana warto\u015bci\u0105 25 i na wyj\u015bciu otrzymamy 25 25.<\/li>\n<\/ol>\n<p>Zobaczmy, co w\u0142a\u015bciwie si\u0119 stanie!<\/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=%40file%3Alesson11b%2Fexample-pl.py&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>Widzimy, \u017ce zachowanie Pythona jest zgodne z wariantem #1. W rzeczywisto\u015bci, <em>za ka\u017cdym razem, gdy funkcja jest wywo\u0142ywana, nie mo\u017cna wp\u0142yn\u0105\u0107 na \u017cadn\u0105 zmienn\u0105 zdefiniowan\u0105 poza t\u0105 funkcj\u0105<\/em>. Wszelkie instrukcje przypisuj\u0105ce warto\u015bci zmiennym maj\u0105 wp\u0142yw tylko na \"lokaln\u0105\" zmienn\u0105, kt\u00f3ra jest \"wewn\u0105trz\" wywo\u0142ywanej funkcji. <strong>Pow\u00f3d<\/strong>, dla kt\u00f3rego Python i wi\u0119kszo\u015b\u0107 innych j\u0119zyk\u00f3w dzia\u0142aj\u0105 w ten spos\u00f3b, sprawiaj\u0105, \u017ce du\u017co prostsze jest napisanie d\u0142ugich program\u00f3w z wieloma funkcjami. W szczeg\u00f3lno\u015bci, kiedy definiujemy now\u0105 funkcj\u0119, zawsze mo\u017cemy u\u017cywa\u0107 dowolnych nazw zmiennych wewn\u0105trz funkcji (w tym takich, jak <code>result,<\/code> <code>temp<\/code> i <code>i<\/code>), nawet je\u015bli s\u0105 one u\u017cywane gdzie indziej w innych celach.<\/p>\n<p>Aby zobaczy\u0107 to szczeg\u00f3\u0142owo, sp\u00f3jrz na \"Krok 6 z 8\" w wizualizatorze. Zauwa\u017c, \u017ce istniej\u0105 dwie r\u00f3\u017cne zmienne <code>warto\u015bci:<\/code> jedna wewn\u0105trz funkcji <code>square<\/code> i jedna na zewn\u0105trz (w obszarze \"globalnym\").<\/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'>Wewn\u0105trz i na Zewn\u0105trz<\/span><\/div><div>Co otrzymamy na wyj\u015bciu nast\u0119puj\u0105cego programu? <\/p>\n<pre>x = \"outer\"<br\/>def xReplace(value):<br\/>   x = value<br\/>xReplace(\"inner\")<br\/>print(x)<\/pre> <\/div><label>Your choice: <\/label><select id=\"pyselect0\"><option value=\"d\" selected>Select one<\/option><option value=\"r\">outer<\/option><option value=\"w\">The program causes an error.<\/option><option value=\"w\">inner<\/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\">Poprawnie! Instrukcja <code>x = value<\/code> wp\u0142ywa tylko na lokaln\u0105 wersj\u0119 zmiennej <code>x<\/code> wewn\u0105trz funkcji. Globalna wersja <code>x<\/code> nie zmienia si\u0119. (Wi\u0119c funkcja <code>xReplace<\/code> jest bezu\u017cyteczna i nigdy nie daje \u017cadnego efektu.)<\/div><\/div>\n<p>Inn\u0105, podobn\u0105 koncepcj\u0105 do <em>zakresu<\/em> jest <em>przestrze\u0144 nazw<\/em>; Przestrze\u0144 nazw jest jak zakres pakietu. Tak wi\u0119c, je\u015bli nawet <code>zaimportujesz<\/code> pakiet (np. <code>math<\/code>), w kt\u00f3rym u\u017cyto nazwy zmiennej <code>x<\/code>, nie pokrywaj\u0105 si\u0119 one ze zmienn\u0105 <code>x<\/code> u\u017cywan\u0105 przez program, poniewa\u017c le\u017c\u0105 w r\u00f3\u017cnych przestrzeniach nazw.<\/p>\n<h2>Patrz\u0105c na Zewn\u0105trz<\/h2>\n<p>S\u0105 sytuacje, w kt\u00f3rych chcemy zmiesza\u0107 zmienne z zakresu lokalnego i globalnego. Na przyk\u0142ad, mamy pewn\u0105 zmienn\u0105 zainicjowan\u0105 na pocz\u0105tku programu, ale chcemy, aby nasze wywo\u0142ywane funkcje by\u0142y w stanie odczyta\u0107 t\u0105 zmienn\u0105.<\/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>Odczytywanie globalnej zmiennej z wn\u0119trza funkcji<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=\"ebcc525a96b4049fa07a711b4c4a3ea4\"\/>\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>Tutaj, zakres lokalny nie zawiera\u0142 zmiennej o nazwie <code>favouriteTopping<\/code>, <em>ale nie spowodowa\u0142o to b\u0142\u0119du<\/em>. Regu\u0142a Pythona do sprawdzania zmiennych polega na tym, \u017ce je\u015bli sprawdzana zmienna nie istnieje w zasi\u0119gu lokalnym, to szukana jest w zasi\u0119gu globalnym. W naszym przypadku, rzeczywi\u015bcie, <code>favouriteTopping<\/code> zosta\u0142a znaleziona w zasi\u0119gu globalnym. (W bardziej og\u00f3lnym przypadku, gdy jedna funkcja cia\u0142a wywo\u0142uje inn\u0105 funkcj\u0119, mamy trzy zakresy: Python zawsze najpierw sprawdza zakres \"najbardziej lokalny\" i przechodzi krok po kroku do zakresu globalnego, dop\u00f3ki nie zostanie znaleziona zmienna).<\/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> Dwa z powy\u017cszych przyk\u0142ad\u00f3w, z <code>orderPizzas<\/code> i <code>xReplace<\/code> s\u0105 pod wzgl\u0119dem sk\u0142adniowym niemal identyczne. Dlaczego Python tworzy now\u0105 lokaln\u0105 zmienn\u0105 <code>x<\/code> w <code>xReplace<\/code>, ale nie ma nowego <code>favouriteTopping<\/code> w <code>orderPizzas<\/code>? Regu\u0142a Pythona jest nast\u0119puj\u0105ca: je\u015bli tylko czytasz zmienn\u0105, to nie tworzona jest \u017cadna nowa lokalna zmienna; ale je\u015bli zapisujesz do zmiennej, cho\u0107by tylko raz, to zmienna jest traktowana jako lokalna w ciele funkcji. (Jest to najcz\u0119stsza przyczyna <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>:\u00a0zobacz te dwa pytania [<a href=\"http:\/\/docs.python.org\/py3k\/faq\/programming.html#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value\" target=\"_blank\">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\">2<\/a>] w oficjalnej dokumentacji Pythona.) <\/span><\/td><\/table><\/p>\n<p>Argumenty funkcji s\u0105 <em>zawsze<\/em> traktowane jako nowe lokalne zmienne, jak pokazano poni\u017cej we fragmencie kodu (pr\u00f3buje zresetowa\u0107 zmienn\u0105 <code>g<\/code> do <code>0<\/code>, ale nie powiedzie si\u0119).<\/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>\u00a0Zmiany <code>global<\/code><\/h2>\n<p>Podobnie jak wiele innych rzeczy, normalna procedura dzia\u0142a, jak opisano powy\u017cej, dla 99% wszystkich sytuacji. Ale dla  1% nie, a ty mo\u017ce naprawd\u0119 chcesz zmieni\u0107 zmienn\u0105 globaln\u0105 z poziomu funkcji. Python zawsze pozwala to zrobi\u0107 z u\u017cyciem instrukcji <code>global<\/code>.<\/p>\n<p>Oto modyfikacja wcze\u015bniejszego przyk\u0142adu <code>xReplace<\/code>; deklarowanie w funkcji zmiennej jako <code>global<\/code> umo\u017cliwia zmian\u0119 warto\u015bci globalnej z poziomu tej funkcji.<\/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=%40file%3Alesson11b%2Freplace-pl.py&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>Jak wspomniano wcze\u015bniej, <em>odczytywanie<\/em> globalnej zmiennej nie wymaga u\u017cycia instrukcji <code>global<\/code>; tylko zapisywanie. To wniosek z tej lekcji!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Lekcja 11 sk\u0142ada si\u0119 z trzech cz\u0119\u015bci A, B, C, kt\u00f3re mo\u017cesz wykona\u0107 w dowolnej kolejno\u015bci. W tej lekcji wyja\u015bnimy poj\u0119cie zakresu zmiennej. G\u0142\u00f3wn\u0105 ide\u0105 to, \u017ce mog\u0105 istnie\u0107 dwie r\u00f3\u017cne zmienne o tej samej nazwie, gdy maj\u0105 r\u00f3\u017cne zakresy. &hellip; <a href=\"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/11b-pl\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-9977","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages\/9977","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\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/comments?post=9977"}],"version-history":[{"count":15,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages\/9977\/revisions"}],"predecessor-version":[{"id":10320,"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/pages\/9977\/revisions\/10320"}],"wp:attachment":[{"href":"https:\/\/cscircles.cemc.uwaterloo.ca\/dev\/wp-json\/wp\/v2\/media?parent=9977"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}