Upload
quilla
View
28
Download
4
Embed Size (px)
DESCRIPTION
Namnrum, räckvidd och rekursion. Linda Mannila 29.11.2007. Liten repetition om funktioner. Vad händer om man i en funktion har en variabel med samma namn som en variabel på yttersta nivån (rotnivån)? Hur kan Python i sådana fall skilja på variablerna?. Namnrum ( namespaces ). - PowerPoint PPT Presentation
Citation preview
Namnrum, räckvidd och rekursionLinda Mannila 29.11.2007
Liten repetition om funktioner Vad händer om man i en funktion
har en variabel med samma namn som en variabel på yttersta nivån (rotnivån)?
Hur kan Python i sådana fall skilja på variablerna?
Namnrum (namespaces) Alla namn ordnas i namnrum
Inte bara variabelnamn, utan även namn på funktioner etc.
Varje namn får endast förekomma en gång i ett namnrum Men samma namn får finnas i godtyckligt många
namnrum utan att störa varandra På rotnivån finns ett globalt namnrum som
alltid finns tillgängligt Inne i en funktion finns ett lokalt namnrum
som endast finns tillgängligt inne i den funktionen
Funktionen dir() visar alla namn som finns definierade i det aktuella namnrummet
>>> dir()['__builtins__', '__doc__', '__name__']
>>> min_variabel = 3>>> dir()['__builtins__', '__doc__', '__name__', 'min_variabel']
>>> def min_funktion():print "Jag är min egen funktion!"
>>> dir()['__builtins__', '__doc__', '__name__', 'min_funktion', 'min_variabel']
>>> def min_funktion():print "Jag är en annan funktion med samma namn. Då försvinner"print "den första versionen för ett namnrum kan inte innehålla"print "fler än en version av ett namn."
>>> dir()['__builtins__', '__doc__', '__name__', 'min_funktion', 'min_variabel']
>>> min_funktion()Jag är en annan funktion med samma namn. Då försvinnerDen första versionen för ett namnrum kan inte innehålla fler än en version av ett namn.
Räckvidd (scope) En variabels räckvidd definieras som
den programkod som har tillgång till det namnrum där variabeln finns definierad
En variabels räckvidd anger var variabeln “syns” utgörs av det block som den definierats i,
med start från den plats där den definierats
Därför syns t.ex. en lokal variabel i en funktion inte utanför funktionen
Hur hittar Python rätt namn? Då en funktion körs
Söker Python först efter namnet i det lokala namnrummet (dvs. inne i funktionen)
Om variabeln inte hittas där, fortsätter Python söka i det globala namnrummet
Om variabeln inte hittas där, fortsätter Python söka i det inbyggda namnrummet
Om variabeln inte heller hittas där, uppstår ett fel
Vilka namn hittas var?def get_info(): text = raw_input("Input info. Any info: ") return text
def get_second_info(): text = raw_input("Input some other info. Any other info: ") return text
info = get_info()info2 = get_second_info()
all_info = info + info2all_info = all_info.upper()print all_info
Skillnad?def get_info(): text = raw_input("Input info. Any info: ") return text
def get_second_info(): text = raw_input("Input some other info. Any other info: ") return text
def main(): info = get_info() info2 = get_second_info()
all_info = info + info2 all_info = all_info.upper() print all_info
Lokala vs. globala variabler Variabler som deklareras inne i
en funktion är inte relaterade till andra variabler med samma namn utanför funktionen Variablerna är lokala för funktionen Variablernas räckvidd är just den
funktionen, inget annat Kan lista de lokala och globala
variablerna i ett program var som helst med funktionerna locals() och globals()
Exempeldef function(): x = 2 print 'Changed local x to', x
x = 50print 'x is', xfunction()print 'x is still', x
Output:x is 50Changed local x to 2x is still 50
Exempeldef function(): x = 2 print 'Changed local x to', x print 'Local variables inside the function: ', locals()
x = 50print 'x is', xfunction()print 'x is still', xprint 'Local variables outside of the function: ', locals()
Outputx is 50Changed local x to 2Local variables inside the function: {'x': 2}x is still 50Local variables outside of the function: {'function': <function function at 0x02AC4E70>, '__builtins__': <module '__builtin__' (built-in)>, '__file__': 'C:\\Python25\\Lib\\idlelib\\idle.pyw', 'idlelib': <module 'idlelib' from 'C:\Python25\lib\idlelib\__init__.pyc'>, 'x': 50, '__name__': '__main__'}
Parametrar blir också lokala variablerdef upphoj(tal, potens): print locals() return tal**potens
print upphoj(5,2)print talprint potens
Output:
{'tal': 5, 'potens': 2}25
Traceback (most recent call last): File "local_global4.py", line 6, in <module> print talNameError: name 'tal' is not defined
Namnrum och moduler Om en modul importeras med import modulnamn måste modulens namn användas som ”prefix” för att
komma åt modulens funktioner
Detta kan undvikas genom att använda from modulnamn import *
eller from modulnamn import namn
Men! Om två moduler definierar samma namn som båda importeras till programmet sker en krock
Den andra importen skriver över gamla definitioner T.ex. om vi skulle göra importen
from webbrowser import open
skulle vi inte längre kunna komma åt den inbyggda funktionen open för att öppna filer
Använd därför from-formen sparsamt
Frågor?
Rekursion Fråga: Vad är rekursion? Svar: Något som definieras rekursivt
Fråga: Vad betyder rekursiv? Svar: En metod som är rekursiv är definierad
genom rekursion.
Fråga: Vad är rekursion? Svar: Något som definieras rekursivt
osv.
Rekursion En rekursiv definition är definierad
utgående från sig själv: "Rekursion: ... För mer information, se
Rekursion. “
En funktion är rekursiv om dess definition innehåller ett anrop till sig själv def minfunktion():
kod... kod... return minfunktion() + 1
Varför rekursion? Ibland är ett problem för stort eller för
komplext för att kunna lösas utan att bli alltför stort
Lösning: bryt ner problemet i mindre delar av sig självt lös dessa delar skilt för sig kombinera alla dellösningar för att få en lösning
till det ursprúngliga problemet
”Divide and conquer”
Rekursion är en bra teknik som kan användas på många intressanta problem.
När används rekursion? Många kända rekursiva exempel
Summaberäkning Fakultet Fibonacci Towers of Hanoi Binary search Quick sort Mergesort ...
Se http://www.sparknotes.com/cs/recursion/examples/
Alla algoritmer som bygger på iteration (loopar) kan även skrivas rekursivt och vice versa
Standardexempel: Fakultet (n!) 0! = 1 1! = 1 n! = n * (n-1)! Rekursiv definition
osv.
Att koda rekursivt En rekursiv funktion är uppbyggd av två element
som alltid måste finnas med Ett basfall Ett rekursivt anrop
Basfallet det undantag som får den rekursiva funktionen
att avslutas får aldrig vara rekursivt, skall oftast returnera ett
enkelt värde Det rekursiva anropet
det som skall ske om inte basfallet gäller anropar den egna funktionen OBS! Som i en while-loop måste man se till att
något ändras för att “minska problemet” för varje rekursivt anrop
Rekursiv fakultet i Pythondef factorial(n): # Basfallet if n == 0 or n == 1: return 1 # Rekursiva anropet else: return n * factorial (n-1)
Rekursiv fakultet - exekveringenfactorial(5)
5 * factorial(4)
4 * factorial(3)
3 * factorial(2)
2* factorial(1)
1 * 1
Basfallet har nåtts!Kan börja ”nysta upp”exekveringen
Rekursiv fakultet - exekveringenfactorial(5)
5 * factorial(4)
4 * factorial(3)
3 * factorial(2)
2* factorial(1)
1 * 1
1*1=1
2*1=2
3*2=6
4*6=24
5*24=120
Rekursiv summadef summa(n): # Basfall if n == 1: return 1 # Rekursivt anrop else: return n + summa(n-1)
Iterativ summadef summa(n): i = 1 summa = 0 while i <= n: summa += i i += 1 return summa
Rekursion vs. iteration Vad är bättre?
Rekursion ger ett stort antal funktionsanrop kostsamt då det slukar mycket
minne långsammare än iteration
Rekursiva funktioner är kortare lättare att skriva och debugga
Rekursion - checklista En rekursiv funktion måste ha
(minst) ett basfall
En rekursiv funktion måste ha (minst) ett rekursivt anrop
Varje rekursivt anrop måste “minska på problemet”
Fibonacci Sanskrit, ideala bisamhällen,
gyllene snittet, Åbo Energis skorsten..
Definieras enligt: fib(0) = 0 fib(1) = 1 fib(n-1) + fib(n-2) för alla n > 1
fibonacci.py