1 of 19

2 of 19

Funkcje - przypomnienie

  • obiekty (def tworzy obiekt)
  • maksymalizacja ponownego wykorzystania kodu
  • minimalizowanie powtarzalności kodu
  • podzielenie problemu na części
  • polimorficzne
  • mogą mieć adnotacje(python 3+)

3 of 19

Przykłady

def intersect(seq1, seq2):� return [x for x in seq1 if x in seq2]

��print(intersect([1,2,3], (2,3)))

[2, 3]

def fun(a: "int", b: "Cos co mozna mnozyc"):� print(a)� def fun_in_fun(a):� print(a*3)� fun_in_fun(b)� fun.c = 12�

fun(2, 5)�fun(2, "spam")�print(fun.c)

print(fun.__annotations__)

2�15�2�spamspamspam�12�{'b': 'Cos co mozna mnozyc', 'a': 'int'}

polimorfizm

adnotacje (py 3+)

obiekt

4 of 19

Argumenty w funkcji

Nasze stałe dla przykładów:

N = 5�power_of_two = [x ** 2 for x in range(N)]

def fun(a):� a = 23��fun(N)�fun(power_of_two)�print(N, power_of_two)

def fun_mutable(a):� a.append(9)��fun_mutable(power_of_two)�print(power_of_two)

def fun_default(a=[]):� a.append(2)� print(a)��for _ in range(4):� fun_default()

(5, [0, 1, 4, 9, 16])

[0, 1, 4, 9, 16, 9]

[2]

[2, 2]

[2, 2, 2]

[2, 2, 2, 2]

5 of 19

Reguła LEGB w funkcjach

  • Local - zakres lokalny
  • Enclosing - zakres lokalny funkcji domykającej
  • Global - zakres globalny (modułu)
  • Bulit-in - wbudowane

L

E

G

B

Graficznie

6 of 19

Zakresy

def show_enclosing(a):� def enclosing():� print("Enclosing: %s" % a)� enclosing()��show_enclosing(5)

def show_local():� x = 23� print("Local: %s" % x)��show_local()

x = 43�def show_global():� print("Global %s" % x)��show_global()

def show_built():� print("Built-in: %s" % abs)��show_built()�import builtins # py3print(dir(builtins))�# print(dir(__builtins__)) #py 2.7

Enclosing: 5

Local: 23

Global 43

Built-in: <built-in function abs>

7 of 19

Zakresy

x = 43�def what_x():� print(x)� x = 4��what_x()

UnboundLocalError: local variable 'x' referenced before assignment

x = 43�def encl_x():� x = 23� def enclosing():� print("Enclosing: %s" % x)� enclosing()��encl_x()

x = 43�def what_about_globals():� global x� x = 37� print("In function %s" % x)��what_about_globals()�print("After function %s" % x)

Enclosing: 23

In function 37

After function 37

x = 43�def what_about_nonlocals():� x = 28� print("Function before enclosing: %s" % x)� def enclosing():� nonlocal x� x = 23� print("Enclosing %s" %x)� enclosing()� print("Function %s" %x)��what_about_nonlocals()

Function before enclosing: 28

Enclosing 23

Function 23

python 3+

8 of 19

Zakresy

x = 43�def main_import():� import __main__� __main__.x = 33��main_import()�print(x)

def fun():� x = fun.l*23� fun.l += 2� print(x)�fun.l = 1�fun()�fun()

33

23

69

Tak lepiej nie kodzić :)

9 of 19

Fabryki funkcji

W skrócie funkcje tworzące nowe funkcje.

def powerer(power):� def nested(number):� return number ** power� return nested

square = powerer(2)��print(square(10))�print(powerer(2)(4))

functions = [powerer(i) for i in range(1,5)]��print(functions[3](4))

def co_ile(start):� def nested(label):� print(label, nested.state)� nested.state += 1� nested.state = start� return nested���f = co_ile(0)�f("foo")�f("bar")��g = co_ile(42)�g("foo")�f("foo")

100

16

256

('foo', 0)�('bar', 1)

�('foo', 42)�('foo', 2)

10 of 19

Funkcje anonimowe

Funkcje anonimowe tworzy się za pomocą wyrażenia lambda

x = lambda : 2

def x():� return 2

print((lambda x,y: x*y)(2,4))

l = [(lambda x: x**2 if x > 2 else x), (lambda x: x**3), (lambda x: x**4)]�for f in l:� print(f(2))

8

2

8

16

11 of 19

Funkcje anonimowe - przyklady

import random�lista_nieuporzadkowana = [(elem,random.randint(0, 30)) for elem in range(10)]�lista = [x for x in range(10)]��print(lista_nieuporzadkowana)

print(sorted(lista_nieuporzadkowana, cmp = lambda x, y: cmp(x[1], y[1]))) #tak nie robic! duzo porownan

print(sorted(lista_nieuporzadkowana, key = lambda x: x[1]))��print(sorted(lista_nieuporzadkowana))

[(4, 15), (2, 19), (3, 20), (0, 22), (1, 24)]

[(4, 15), (2, 19), (3, 20), (0, 22), (1, 24)]

[(0, 22), (1, 24), (2, 19), (3, 20), (4, 15)]

[(0, 22), (1, 24), (2, 19), (3, 20), (4, 15)]

#wywodzi sie z jezykow funkcyjnych w py 3 trzeba dodac listprint(map(lambda x: x**2, lista))�print(filter(lambda x: x>0, range(-5,5)))�print(reduce(lambda a,b : a+b, range(0, 10)))

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

[1, 2, 3, 4]

45

12 of 19

Generatory - jednorazowe iteratory

Funkcje moga zwracać wartość cząstkową, zapisując swój aktualny stan, aby po wznowieniu mogły kontynuować od miejsca gdzie się ostatnio zatrzymała.

def gensquares(n):� for i in range(n):� yield i ** 2��print(gensquares(10))��print(list(gensquares(10)))

(5*i for i in range(20))

<generator object gensquares at 0x1043a4be0>

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

<generator object <genexpr> at 0x1043a4c30>

def f():� yield #Noneprint(2)� yield��x = f()�next(x)�next(x)

2

13 of 19

Iteracja w pythonie

def gensquares(n):� for i in range(n):� yield i ** 2

x = gensquares(3)

next(x)

next(x)

next(x)

next(x)

0

1

4

StopIteration

Tak samo każdy obiekt iterowalny np. lista:

l = [1,2,3]�i = iter(l)�next(i)�next(i)�next(i)�next(i)

1

2

3

StopIteration

W skrócie kiedy korzystamy z for’a to python sam robi sobie iterator i przechodzi po nim aż do StopIteration :)

14 of 19

Gdzie są generatory + bonus

  • range (w pythonie 3), xrange (w pythonie 2)
  • map, filter (python 3)
  • pliki

def gen():� for i in range(10):� x = yield i� print(x)��x = gen()

print(next(x))�print(next(x))�print(x.send(43))�print(next(x))�print(next(x))

Wysłanie czegoś do generatora

0�

None

1�

43

2�

None

3�

None

4

15 of 19

Importowanie

  • odbywa się tylko raz
  • from x import *
  • importowanie wzgledne

from module import name1, name2��import module�name1 = module.name1�name2 = module.name2�del module

#jestesmy w A.B.C��from . import D # A.B.Dfrom .. import E # A.Efrom .D import X # A.B.D.Xfrom ..E import X # A.E.X

16 of 19

Context manager czyli with

with wyrażenie [as zmienna]:

block_with

Wyrażenie jest context managerem czyli wykonuje przed rozpoczęciem i po skończeniu funkcję block_with (ustawienie i wyczyszczenie danych).

with open("file", 'w') as f:� f.write("Hello file")

Nie musimy zamykać pliku, context manager zrobi to za nas

Tworzy się je za pomocą klas, istnieje też skrót from contextlib import contextmanager , który jest dekoratorem - o tym na następnej prezentacji! :)

17 of 19

Pliki

Mamy 3 tryby otwierania plików: r, w, a (read, write, append).

Możemy dodać do każdego + co oznacza aktualizacje. Więcej o trybach.

f = open("file", "r+")�all_file = f.read()�f.write("\nEnd")�f.close()��with open("file", "r+") as f:� for line in f:� print(line.rstrip())� f.seek(0)� print(f.read(4))� f.seek(11)� print(f.readline())� f.seek(0)� print(f.readlines())

Hello file

End

Hell

End

['Hello file\n', 'End']

18 of 19

Zadania

0. Wszystkie rozwiązania napisz w postaci funkcji w module o nazwie rozwiazania.py

1. Wygeneruj plik zawierajacy pierwiastki kolejnych liczb od 0 do 36 - w każdej linii jeden.

2. Wczytaj plik z poprzedniego zadania. Oblicz sumę pierwiastków. Następnie dopisz na końcu pliku otrzymany wynik.

3. Napisz funkcje tworząca funkcje (fabryka) która przyjmuje stringa, a zwraca ile razy (dotychczas) został podany ten właśnie string jako argument - wykorzystaj zagnieżdżone def w def oraz metodę setdefault dla słowników.

4. Napisz generator dla kolejnych potęg liczby 2, aż do 10. Zastosuj obie składnie podane na wykładzie.

1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024

counter = fun()�counter("spam")�counter("food")�counter("food")

0

0

1

Dostępne pod adresem: tinyurl.com/pycircle

19 of 19

Zadania

5. Wygeneruj liste 10 losowych liczb z zakresu 25 do 75. Posortuj je w kolejności odwrotnej. (największa liczba ma być pierwszą w liście). Czy potrzebna jest do tego lambda?

np. [73, 62, 55, 51, 49, 45, 44, 42, 29, 27]

6. Wykorzystując funkcje anonimowe wyfiltruj z listy [9,3,24,5,12,17,16, 93,1,203, 27, 93] liczby podzielne przez 3.

[9, 3, 24, 12, 93, 27, 99]

7. Napisz funkcje która bedzie zachowywała się tak samo jak join za pomocą funkcji reduce() oraz funkcji anonimowych(w pythonie 3.3 reduce jest w module functools)

print(fjoin(" ", ['foo', 'bar', 'spam']))

foo bar spam