Funkcija, objekt, python

42
funkcija, objekt, python Robert Lujo

description

Funkcije u pythonu, funkcijska paradigma, high order functions, first class citizens, closures, decorators

Transcript of Funkcija, objekt, python

Page 1: Funkcija, objekt, python

funkcija, objekt, python

!Robert Lujo

Page 2: Funkcija, objekt, python

o meni

• software

• profesionalno 17 g.

• python od 2.0, django od 0.96

• freelancer

• ostalo na linkedin-u

Page 3: Funkcija, objekt, python

funkcija

a function/subroutine/procedure/routine/method/subprogram is a sequence of program instructions that perform a specific task, packaged as a unit

https://en.wikipedia.org/wiki/Function_(programming)

Page 4: Funkcija, objekt, python

funkcija u pythonu

Sve što zadovoljava:

callable(f)

hasattr(f, “__call__”)

Page 5: Funkcija, objekt, python

primjer

def f(s):

print(“hello”, s)

>>> callable(f); hasattr(f,”__call__”)

True, True

Page 6: Funkcija, objekt, python

funkcija je FCC

first class citizen - is an entity which supports all the operations generally available to other entities.

These operations typically include being passed as a parameter, returned from a function, and assigned to a variable.

https://en.wikipedia.org/wiki/First-class_citizen

Page 7: Funkcija, objekt, python

funkcija kao i svaki drugi objekt

>>> def f(s): ... "pydoc ..." ... return "hello %s" % s !>>> type(f) <type ‘function’> !>>> dir(f) ['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__globals__', '__init__', '__module__', '__name__', … 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', ‘func_name’]

>>> g = f # dodijeli varijabli

>>> f(f) # proslijedi kao parametar

'hello <function f at 0x10b66bb90>'

Page 8: Funkcija, objekt, python

par atributa …>>> def f(s): ... "pydoc dokumentacija" ... return "hello %s" % s !!>>> f.__globals__ {'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', 'f': <function f at 0x10b66b5f0>, '__doc__': None, '__package__': None} !>>> f.__doc__ 'pydoc dokumentacija' !>>> f.__name__ 'f' !>>> f.__code__ <code object f at 0x10b639030, file "<stdin>", line 1> !>>> f.__closure__ >>> f.__defaults__ >>> f.__dict__

Page 9: Funkcija, objekt, python

lambda expression• izraz, nije naredba, vrlo ograničeno, ne može sadržavati naredbe

• vraća objekt funkcije

• korisno: gdje god može ići izraz, tamo se može staviti lambda

>>> f = lambda x: x*2

>>> f(3) -> 6

>>> type(f); dir(f)

<type ‘function’>, ['__call__', ‘__class__’..

>>> (lambda x: x*2)(3) -> 6

Page 10: Funkcija, objekt, python

objekt kao funkcija• vrlo jednostavno -> implementirati __call__ metodu

• objekt nije tipa “function” već F, ipak se razlikuje od standardne funkcije

!class F(object): def __call__(self, s): return "hello %s" % s !>>> f = F() >>> f("world") 'hello world' !>>> callable(f) True >>> dir(f) ['__call__', '__class__', '__delattr__', '__dict__', '__doc__', …]

Page 11: Funkcija, objekt, python

klasa je object factory funkcija

class C(object): pass !>>> callable(C) True !# klasa je funkcija koja vraća novi objekt >>> C() <__main__.C object at 0x10b669bd0> >>> C() <__main__.C object at 0x10b691b33>

Page 12: Funkcija, objekt, python

metoda = priljepljena funkcijaclass C(object): def m(self, s): return "method %s" % s !>>> C.m, C().m <unbound method C.m>, <bound method C.m of <__main__.C object at 0x10b669bd0>> !>>> dir(C.m) ['__call__', … , 'im_class', 'im_func', 'im_self'] !>>> C.m==C().m False !>>> C.m.im_self, C().m.im_self None, <__main__.C object at 0x10b669bd0> !>>> C().m.im_func, C().m.im_func == C.m.im_func <function m at 0x10b66b5f0>, True

Page 13: Funkcija, objekt, python

dinamička metoda - dodati na klasu

class C(object):

pass

!

>>> def m(self, s):

return "hello %s" % s

!

>>> C.m = m

>>> C().m("world")

'hello world'

Page 14: Funkcija, objekt, python

dinamička metoda - dodati na objekt

class C(object):

pass

!

>>> def m(self, s):

return "hello %s" % s

>>> o = C()

>>> import types

>>> o.m = types.MethodType( m, o )

>>> o.m("world")

'hello world'

Page 15: Funkcija, objekt, python

s metodom je jednostavnijeclass C(object): def __str__(self): return "Object %s" % id(self) __repr__ = __str__ !>>> o = C() >>> repr(o), str(o) 'Object 4486241936’, 'Object 4486241808' !>>> o.x = o.__str__ >>> o.x() 'Object 4486241808'

Page 16: Funkcija, objekt, python

vlastiti atribut funkcijeclass C(object): def m(self): return 1 m.is_test = 1 !def x(): return 2 x.is_test = 3 !>>> x.is_test 3 >>> C.m.is_test 1

Page 17: Funkcija, objekt, python

argumenti funkcijedef f(a1, *args, **kwargs): print a1, args, kwargs !

>>> f(1,2,x=3) 1 (2,) {'x': 3} !

>>> f(1, *[2,3], **{“x”: 4}) 1 (2, 3) {'x': 4}

Page 18: Funkcija, objekt, python

self“self” u metodi je samo konvencija, tj. ovo je valjani kod:!!

class C(object): def set_x(zeko_mrkva, x): zeko_mrkva.x = x !

>>> o = C(); o.set_x(3); print o.x 3

Page 19: Funkcija, objekt, python

high order functions(also functional form, functional or functor) is a function that does at least one of the following:

1. takes one or more functions as an input!

2. outputs a function!

All other functions are first-order functions.

https://en.wikipedia.org/wiki/Higher-order_function

Page 20: Funkcija, objekt, python

nabacujemo se funkcijama

def add(a,b): return a+b !

def operation_with_3(f_op, a): return f_op(a,3) !

>>> operation_with_3(add, 2) 5

Page 21: Funkcija, objekt, python

i još …def add(a,b): return a+b !def subs(a,b): return a-b !def get_f_op(op_name): return globals()[op_name] # vraća funkciju !>>> get_f_op("add") <function add at 0x10b66ba28> !>>> get_f_op("add")(3,4) 7 >>> get_f_op("subs")(3,4) -1

Page 22: Funkcija, objekt, python

funkcijska paradigmaa style of building .. computer programs, that treats computation as the evaluation of mathematical functions and avoids state and mutable data.

emphasizes functions that produce results that depend only on their inputs and not on the program state — i.e. pure mathematical functions.

https://en.wikipedia.org/wiki/Functional_paradigm

Page 23: Funkcija, objekt, python

laički• nema “side-effects”

• nema mutable objekata tj.

svaka promjena -> novi objekt

• u praksi:

funkcije, immutable objekti: primitivni, liste, dictionaries

flow: funkcija zove funkciju koja zove funkciju koja prosljeđuje funkciju koja vraća funkciju …

Page 24: Funkcija, objekt, python

python i funkcijska paradigma

• python se klasificira kao “multi-paradigm”

• “implementira” i funkcijsku paradigmu

• u praksi se vidi puno više objektne paradigme

• funkcijsko - nasljeđe i novije

Page 25: Funkcija, objekt, python

builtins>>> map(lambda x: x+1, (1,2,3)) [2, 3, 4] !>>> reduce(lambda r,n: r + [r[-1]+n], [1,2,3], [0]) [0, 1, 3, 6] !>>> filter(lambda x: x>1, (1,2,3)) [2, 3] !>>> any((0,””,True)), all((0,””, True)) True, False !>>> min((3,2,4)), max((3,2,4)) 2 4

Page 26: Funkcija, objekt, python

builtinsfor i, x in enumerate([10, 20, 30]): print "%s. %s, " % (i,x),

0. 10, 1. 20, 2. 30,

!for a,b,c in zip([1,2,3], [10,20], [100, 200]): print "%s %s %s, " % (a,b,c),

1 10 100, 2 20 200,

!# sorted prima i funkcije za određivanje redoslijeda for a in sorted([3,2,4,1], reverse=True): print a,

4,3,2,1

!reversed, (x)range …

Page 27: Funkcija, objekt, python

list comprehensionJedan dio ovih funkcija se može uspješno zamijeniti s “list comprehension”!!Primjeri:!!>>> map(lambda x: x+1, (1,2,3)) == >>> [x+1 for x in (1,2,3)] !!>>> filter(lambda x: x>1, (1,2,3)) == >>> [x for x in (1,2,3) if x>1] !

Page 28: Funkcija, objekt, python

functools.partial

def add(a,b): return a+b !

>>> from functools import partial >>> add_3 = partial(add, 3) >>> add_3(2) 5

Page 29: Funkcija, objekt, python

operator

Standard operators as functions - comparison, bool, math, etc.!!

>>> from functools import partial >>> from operator import add >>> add_3 = partial(add, 3) >>> add_3(2) 5

Page 30: Funkcija, objekt, python

generators• generator expression!

>>> ge = (x+1 for x in range(3)); print ge <generator object <genexpr> at 0x10b664aa0> >>> tuple(ge) (1,2,3)

• yield u funkciji -> poseban oblik funkcije - coroutine, vraća generator object

• coroutine: allow multiple entry points for suspending and resuming execution at certain locations (https://en.wikipedia.org/wiki/Coroutine)

!def go(n): for x in range(n): yield x+1 !>>> go(3) <generator object go at 0x10b664af0> >>> tuple(go(3)) (1,2,3)

Page 31: Funkcija, objekt, python

generators• yield zaustavlja izvođenje funkcije, pamti stanje i prenosi izvođenje natrag na pozivatelja

• poziv generator_object.next() vraća generatorsku funkciju u isti kontekst gdje je stala te funkcija nastavlja do sljedećeg yield-a ili kraja funkcije

• moguće je iz pozivatelja slati informacije natrag generatoru sa generator_object.send() !

def genfun(n): print “in” for x in range(n): y = yield x+1 print “got”, y !>>> go = genfun(3) >>> go.send(None); print “x=“,x in, x=0 !>>> x = go.send(10); print “x=“,x got 10, x=1 !>>> x = go.send(13); print “x=“,x got 13, x=2

Page 32: Funkcija, objekt, python

itertoolsFunctions creating iterators for efficient looping. !

Hrpa brzih funkcija za razno razne manipulacije listama, dictionary-ma i sl. - često primaju funkcije kao parametre: !

Functions creating iterators for efficient looping ! count() cycle() repeat() !Iterators terminating on the shortest input sequence: ! chain() compress() dropwhile() groupby() ifilter() ifilterfalse() islice() imap() starmap() tee() takewhile() izip() izip_longest() !Combinatoric generators: ! product() permutations() combinations() combinations_with_replacement() product('ABCD', repeat=2) permutations('ABCD', 2) combinations('ABCD', 2) combinations_with_replacement('ABCD', 2)

Page 33: Funkcija, objekt, python

closures

is a function or reference to a function together with a referencing environment—a table storing a reference to each of the non-local variables

https://en.wikipedia.org/wiki/Closure_(computer_programming)

Page 34: Funkcija, objekt, python

python function scope• bitno je znati da se “vanjske” varijable vide

def f(a):

b = 1

print globals().keys()

print locals().keys() !>>> f(3) ['__builtins__', '__name__', 'f', '__doc__', '__package__'] ['a', ‘b']

• kad je potrebno mijenjati jednostavnu “vanjsku” varijablu - koristiti “global” statement

Page 35: Funkcija, objekt, python

closures u pythonufunkcija unutar funkcije “vidi” lokalne objekte “vlasnika” funkcije !

def f(a): b = [1,2]

def closure(c): return a+b+c # vidi a i b

return closure([3,4]) !>>> f([0]) # poziva inner funkciju [0, 1, 2, 3, 4]

Page 36: Funkcija, objekt, python

funkcija vraća funkcijufunkcija koja vraća funkciju prilagođenu prema ulaznim parametrima prve funkcije !

def f(a): b = [1,2]

def closure(c): return a+b+c # vidi a i b

return closure !>>> fun = f([0]) # vraća funkciju <function closure at 0x10b66bde8> !>>> fun.__closure__ # je li se tko sjeća ovoga? (<cell at 0x10b6771d8: builtin_function_or_method object at 0x10b6765f0>, <cell at 0x10b677168: list object at 0x10b671758>)

!>>> fun([5,6]) [0, 1, 2, 5, 6]

Page 37: Funkcija, objekt, python

dekorator funkcija - uvoddekorator funkcije je funkcija (1) koja za prvi ulazni parametar prima funkciju (2) i vraća drugu funkciju (3) koja koristi parametar funkciju (1) !

def f(fun, a): # (1) (2) def closure(c): # (3) print "before calling %s(%s, %s)" % (fun.__name__, a,c)

return fun(a,c) # (2)

return closure !>>> def add(x,y): return x+y # (2)

>>> fun = f(add, [0]) # vraća funkciju (3) <function closure at 0x10b66bde8> !>>> fun([7,8]) # poziva (3) before calling add([0], [7, 8]) [0, 7, 8]

Page 38: Funkcija, objekt, python

dekorator funkcijasugar-syntax je @: !

def deco(fun): b = [1,2]

def closure(c): print "before calling %s(%s, %s)" % (fun.__name__, a,c)

return fun(a,c)

return closure !@deco # što je isto kao: add = deco(add) def add(x,y): return x+y

!>>> add([7,8]) before calling add([1, 2], [7, 8]) [1, 2, 7, 8]

Page 39: Funkcija, objekt, python

dekorator s parametrimafunkcija u funkciji u funkciji, 4 funkcije u igri, uff …

def dec_with_args(dec_arg1, dec_arg2): def my_decorator(func): def wrapped(fun_arg1, fun_arg2) : return func(fun_arg1, fun_arg2) return wrapped return my_decorator !@dec_with_args("Leonard", "Sheldon") def dec_fun(fun_arg1, fun_arg2): print ("{0} {1}".format(fun_arg1, fun_arg2)) !dec_fun("Rajesh", "Howard")

Page 40: Funkcija, objekt, python

kako objekt može biti funkcija…

to daje alternativnu metodu za implementaciju dekoratora

class deco(object): def __init__(self, fun): self.fun = fun ! def __call__(self, c): return self.fun([4], c) !@deco def add2(x, y): return x+y !>>> add2([1]) [4, 1]

Page 41: Funkcija, objekt, python

dekorator - zadnji slide :)• osim nad funkcijom - dekorator možemo napraviti i nad:

• metodom

• klasom

• posebna problematika napraviti robustan dekorator koji radi i za klase i za metode i za funkcije

• koristiti functools.wraps za izradu dekoratora

• mogu se nizati - tj. više dekoratora nad istom funkcijom

Page 42: Funkcija, objekt, python

i … to bi bilo to

Hvala na strpljenju!

Pitanja?

!

[email protected]

@trebor74hr