Upgrade to Pro — share decks privately, control downloads, hide ads and more …

python decorators

python decorators

Yura Hulpa

March 02, 2016
Tweet

More Decks by Yura Hulpa

Other Decks in Programming

Transcript

  1. Definition according to GOF Pa erns 1994 Intent A ach

    additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. Also Known As Wrapper Motivation Sometimes we want to add responsibilities to individual objects, not to an entire class. A graphical user interface toolkit, for example, should let you add properties like borders or behaviors like scrolling to any user interface component.
  2. PEP 0318 Decorators for Functions and Methods To manipulate data

    in human readable form def foo(self): perform method operation foo = classmethod(foo)
  3. Simple case # basic decoration with functions def decorate_with_sword(func): def

    func_wrapper(name): return '{} with a SWORD'.format(func(name)) return func_wrapper def orc_attack(name): """function that hit's you! """ return "{} , I am, hitting you".format(name) decorated_with_sword = decorate_with_sword( orc_attack) print decorated_with_sword('Artes') print decorated_with_sword.__doc__ print decorated_with_sword.__name__ >>Artes , I am, hitting you with a SWORD >>None >>func_wrapper
  4. Let’s add some sugar # decorate with syntax sugar def

    decorate_with_sword(func): def func_wrapper(name): return '{} with a SWORD'.format(func(name)) return func_wrapper @decorate_with_sword def orc_attack(name): """function that hit's you! """ return "{}, I am, hitting you".format(name) print orc_attack('Lich King') print orc_attack.__doc__ print orc_attack.__name__ >>Lich King, I am, hitting you with a SWORD >>None >>func_wrapper
  5. Small issue when wrapping into decorator we are loosing wrapped

    function signature Do we care? For debugging for example it would be good to save it
  6. Wrap it all # adding wraps decorator from functools from

    functools import wraps def decorate_with_sword(func): @wraps(func) def func_wrapper(name): return '{} with a SWORD'.format(func(name)) return func_wrapper @decorate_with_sword def orc_attack(name): """function that hit's you! """ return "{} , I am, hitting you".format(name) print orc_attack('Rengar') print orc_attack.__doc__ print orc_attack.__name__ >>Rengar , I am, hitting you with a SWORD >>function that hits you >>orc_attack
  7. Syntax class ClassName(object): @classmethod def string_compare(cls): # code here print

    'I am classmethod' @staticmethod def string_compare(): # code here print 'I am staticmethod'
  8. test it ClassName.string_compare_class => <bound method type.string_compare_class of <class 'ClassName'>>

    ClassName.string_compare_static => <function string_compare_static at 0x168b5c0>
  9. Cls argument class Orc(object): ugly = False @classmethod def get_instance(cls):

    # code here print cls() class UglyOrc(Orc): ugly = True Orc.get_instance() <Orc object at 0x1304da0> UglyOrc.get_instance() <UglyOrc object at 0x13057e0>
  10. Our example code class Date(object): day = 0 month =

    0 year = 0 def __init__(self, day=0, month=0, year=0): self.day = day self.month = month self.year = year
  11. We want to parse and create instances of date day,

    month, year = map(int, string_date.split('-')) date1 = Date(day, month, year)
  12. Usa case of class method class Date(object): day = 0

    month = 0 year = 0 def __init__(self, day=0, month=0, year=0): self.day = day self.month = month self.year = year @classmethod def from_string(cls, date_as_string): day, month, year = map(int, date_as_string. split('-')) date1 = cls(day, month, year) return date1 date2 = Date.from_string('11-09-2012')
  13. Static method class Date(object): day = 0 month = 0

    year = 0 def __init__(self, day=0, month=0, year=0): self.day = day self.month = month self.year = year @staticmethod def is_date_valid(date_as_string): day, month, year = map(int, date_as_string. split('-')) return day <= 31 and month <= 12 and year < = 3999 # usage: is_date = Date.is_date_valid('11-09-2012')
  14. Real life example: Bitcoin class BitCoinTransaction: def __init__(self, date, tid,

    price, amount): self.date = date self.tid = tid self.price = price self.amount = amount @classmethod def dictionary_to_instance(cls, start_dict): """ Return a BitCoinTransaction class instance """ date = datetime.datetime.fromtimestamp(int( start_dict["date"])) tid = int(start_dict["tid"]) price = float(start_dict["price"]) amount = float(start_dict["amount"]) return cls(date, tid, price, amount)