def a_decorator_passing_arguments(function_to_decorate): def a_wrapper_accepting_arguments(arg1, arg2): # print ", :", arg1, arg2 function_to_decorate(arg1, arg2) return a_wrapper_accepting_arguments # , , , # "", # @a_decorator_passing_arguments def print_full_name(first_name, last_name): print " ", first_name, last_name print_full_name("", "") # : # , : # # *
def method_friendly_decorator(method_to_decorate): def wrapper(self, lie): lie = lie - 3 # , - :-) return method_to_decorate(self, lie) return wrapper class Lucy(object): def __init__(self): self.age = 32 @method_friendly_decorator def sayYourAge(self, lie): print " %s, ?" % (self.age + lie) l = Lucy() l.sayYourAge(-3) # : 26, ?
def a_decorator_passing_arbitrary_arguments(function_to_decorate): # "" def a_wrapper_accepting_arbitrary_arguments(*args, **kwargs): print " -?:" print args print kwargs # *args **kwargs # , : # http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/ function_to_decorate(*args, **kwargs) return a_wrapper_accepting_arbitrary_arguments @a_decorator_passing_arbitrary_arguments def function_with_no_argument(): print "Python is cool, no argument here." # , :) function_with_no_argument() # : # -?: # () # {} # Python is cool, no argument here. @a_decorator_passing_arbitrary_arguments def function_with_arguments(a, b, c): print a, b, c function_with_arguments(1,2,3) # : # -?: # (1, 2, 3) # {} # 1 2 3 @a_decorator_passing_arbitrary_arguments def function_with_named_arguments(a, b, c, platypus=" ?"): print " %s, %s %s ? %s" %\ (a, b, c, platypus) function_with_named_arguments("", "", "", platypus="!") # : # -?: # ('', '', '') # {'platypus': '!'} # , ? ! class Mary(object): def __init__(self): self.age = 31 @a_decorator_passing_arbitrary_arguments def sayYourAge(self, lie=-3): # print " %s, ?" % (self.age + lie) m = Mary() m.sayYourAge() # : # -?: # (<__main__ .Mary object at 0xb7d303ac>,) # {} # 28, ?
# - def my_decorator(func): print " " def wrapper(): print " - , " func() return wrapper # , , "@"-: def lazy_function(): print "zzzzzzzz" decorated_function = my_decorator(lazy_function) # : # " ", , : # . @my_decorator def lazy_function(): print "zzzzzzzz" # :
@my_decorator
- we simply say to the interpreter "to call a function called my_decorator ". This is an important point, because this name can either lead us directly to the decorator ... and no!
def decorator_maker(): print " ! : "+\ " ." def my_decorator(func): print " - ! : ." def wrapped(): print (" - . " " . " " .") return func() print " ." return wrapped print " ." return my_decorator # . new_decorator = decorator_maker() # : # ! : . # . # def decorated_function(): print " - ." decorated_function = new_decorator(decorated_function) # : # - ! : . # . # : decorated_function() # : # - . . # . # - .
def decorated_function(): print " - ." decorated_function = decorator_maker()(decorated_function) # : # ! : . # . # - ! : . # . # : decorated_function() # : # - . . # . # - .
@decorator_maker() def decorated_function(): print "I am the decorated function." # : # ! : . # . # - ! : . # . # : decorated_function() # : # - . . # . # - .
def decorator_maker_with_arguments(decorator_arg1, decorator_arg2): print " ! :", decorator_arg1, decorator_arg2 def my_decorator(func): print " - . :", decorator_arg1, decorator_arg2 # ! def wrapped(function_arg1, function_arg2) : print (" - .\n" " : \n" "\t- : {0} {1}\n" "\t- : {2} {3}\n" " " .format(decorator_arg1, decorator_arg2, function_arg1, function_arg2)) return func(function_arg1, function_arg2) return wrapped return my_decorator @decorator_maker_with_arguments("", "") def decorated_function_with_arguments(function_arg1, function_arg2): print (" - : {0}" " {1}".format(function_arg1, function_arg2)) decorated_function_with_arguments("", "") # : # ! : # - . : # - . # : # - : # - : # # - :
c1 = "" c2 = "" @decorator_maker_with_arguments("", c1) def decorated_function_with_arguments(function_arg1, function_arg2): print (" - : {0}" " {1}".format(function_arg1, function_arg2)) decorated_function_with_arguments(c2, "") # : # ! : # - . : # - . # : # - : # - : # # - :
def decorator_with_args(decorator_to_enhance): """ . , . . , , , , . """ # , : def decorator_maker(*args, **kwargs): # , # , , "" def decorator_wrapper(func): # , , , # ( ). # , # decorator(func, *args, **kwargs) # , return decorator_to_enhance(func, *args, **kwargs) return decorator_wrapper return decorator_maker
# , :-) # , "decorator(func, *args, **kwargs)" @decorator_with_args def decorated_decorator(func, *args, **kwargs): def wrapper(function_arg1, function_arg2): print " ...:", args, kwargs return func(function_arg1, function_arg2) return wrapper # , : @decorated_decorator(42, 404, 1024) def decorated_function(function_arg1, function_arg2): print "", function_arg1, function_arg2 decorated_function(" ", " ") # : # ...: (42, 404, 1024) {} # # !
# , __name__ . def foo(): print "foo" print foo.__name__ # : foo # , : def bar(func): def wrapper(): print "bar" return func() return wrapper @bar def foo(): print "foo" print foo.__name__ # : wrapper # "functools" import functools def bar(func): # "wrapper" "func" # : @functools.wraps(func) def wrapper(): print "bar" return func() return wrapper @bar def foo(): print "foo" print foo.__name__ # : foo
def benchmark(func): """ , , . """ import time def wrapper(*args, **kwargs): t = time.clock() res = func(*args, **kwargs) print func.__name__, time.clock() - t return res return wrapper def logging(func): """ , . (, , !) """ def wrapper(*args, **kwargs): res = func(*args, **kwargs) print func.__name__, args, kwargs return res return wrapper def counter(func): """ , . """ def wrapper(*args, **kwargs): wrapper.count += 1 res = func(*args, **kwargs) print "{0} : {1}x".format(func.__name__, wrapper.count) return res wrapper.count = 0 return wrapper @benchmark @logging @counter def reverse_string(string): return str(reversed(string)) print reverse_string(" ") print reverse_string("A man, a plan, a canoe, pasta, heros, rajahs, a coloratura, maps, snipe, percale, macaroni, a gag, a banana bag, a tan, a tag, a banana bag again (or a camel), a crepe, pins, Spam, a rut, a Rolo, cash, a jar, sore hats, a peon, a canal: Panama!") # : # reverse_string (' ',) {} # wrapper 0.0 # reverse_string : 1x # # reverse_string ('A man, a plan, a canoe, pasta, heros, rajahs, a coloratura, maps, snipe, percale, macaroni, a gag, a banana bag, a tan, a tag, a banana bag again (or a camel), a crepe, pins, Spam, a rut, a Rolo, cash, a jar, sore hats, a peon, a canal: Panama!',) {} # wrapper 0.0 # reverse_string : 2x # !amanaP :lanac a ,noep a ,stah eros ,raj a ,hsac ,oloR a ,tur a ,mapS ,snip ,eperc a ,)lemac a ro( niaga gab ananab a ,gat a ,nat a ,gab ananab a ,gag a ,inoracam ,elacrep ,epins ,spam ,arutaroloc a ,shajar ,soreh ,atsap ,eonac a ,nalp a ,nam A
import httplib @benchmark @logging @counter def get_random_futurama_quote(): conn = httplib.HTTPConnection("slashdot.org:80") conn.request("HEAD", "/index.html") for key, value in conn.getresponse().getheaders(): if key.startswith("xb") or key.startswith("xf"): return value return ", ... !" print get_random_futurama_quote() print get_random_futurama_quote() #outputs: #get_random_futurama_quote () {} #wrapper 0.02 #get_random_futurama_quote : 1x #The laws of science be a harsh mistress. #get_random_futurama_quote () {} #wrapper 0.01 #get_random_futurama_quote : 2x #Curse you, merciful Poseidon!
Source: https://habr.com/ru/post/141501/