Your SlideShare is downloading. ×
Funkcija, objekt, python
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Saving this for later?

Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime - even offline.

Text the download link to your phone

Standard text messaging rates apply

Funkcija, objekt, python

245
views

Published on

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

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

Published in: Software

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
245
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
2
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. funkcija, objekt, python ! Robert Lujo
  • 2. o meni • software • profesionalno 17 g. • python od 2.0, django od 0.96 • freelancer • ostalo na linkedin-u
  • 3. 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)
  • 4. funkcija u pythonu Sve što zadovoljava: callable(f) hasattr(f, “__call__”)
  • 5. primjer def f(s): print(“hello”, s) >>> callable(f); hasattr(f,”__call__”) True, True
  • 6. 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
  • 7. 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>'
  • 8. 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__
  • 9. 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
  • 10. 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__', …]
  • 11. 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>
  • 12. metoda = priljepljena funkcija class 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
  • 13. 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'
  • 14. 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'
  • 15. s metodom je jednostavnije class 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'
  • 16. vlastiti atribut funkcije class 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
  • 17. argumenti funkcije def 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}
  • 18. 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
  • 19. 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
  • 20. 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
  • 21. 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
  • 22. funkcijska paradigma a 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
  • 23. 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 …
  • 24. 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
  • 25. 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
  • 26. builtins for 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 …
  • 27. list comprehension Jedan 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] !
  • 28. functools.partial def add(a,b): return a+b ! >>> from functools import partial >>> add_3 = partial(add, 3) >>> add_3(2) 5
  • 29. 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
  • 30. 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)
  • 31. 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
  • 32. itertools Functions 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)
  • 33. 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)
  • 34. 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
  • 35. closures u pythonu funkcija 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]
  • 36. funkcija vraća funkciju funkcija 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]
  • 37. dekorator funkcija - uvod dekorator 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]
  • 38. dekorator funkcija sugar-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]
  • 39. dekorator s parametrima funkcija 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")
  • 40. 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]
  • 41. 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
  • 42. i … to bi bilo to Hvala na strpljenju! Pitanja? ! robert.lujo@gmail.com @trebor74hr