Package: good-handlers
Good HandlersMethod and function handlers that implement common behaviors without writing the entire functionHandlersHandlers are objects that act as methods in a class. They are good for configurable, predefined functions which will otherwise be redundant to implement. Handler functionality is implemented in standard python's__call__method, which otherwise treats the handler like a function.fromgood_handlersimportInstanceHandlerclassMyHandler(InstanceHandler):def__init__(self,scale):self._scale=scaledef__call__(self,instance,arg1,arg2):instance.result=scale*(arg1+arg2)The classInstanceHandlerbinds to an instance. This requires the extrainstanceparameter, which will become the bound instance of the handlerfromgood_handlersimportInstanceHandlerclassMyHandler(InstanceHandler):def__init__(self,scale,save='last_result'):self._scale=scaleself._save=savedef__call__(self,instance,arg1,arg2):setattr(instance,self._save,scale*(arg1+arg2))classMyClass:def__init__(self):self.last_result=Nonehandler=MyHandler(3)The classClassHandlerbinds to a class and passes the bound class to the extraklassparameter.fromgood_handlersimportClassHandlerclassDefaultAgePersonMaker(ClassHandler):def__init__(self,defage):self._defage=defagedef__call__(self,klass,name):returnklass(name=name,age=self._defage)classPerson:make_twenty_year_old=DefaultAgePersonMaker(20)def__init__(self,name,age):self._name=nameself._age=agejim=Person.make_twenty_year_old('Jim Shim')# Makes Person('Jim Shim', 20)Init HandlersA special case of redundant programming is the__init__method. Often times, the__init__is only used to set a series of member variables. Thus, they will often contain a lot of boilerplate code. The Good Library offers a few__init__handlers, which simplify creating__init__methods.NamedInitHandlersets member variables according to a tuple of names provided in thenamesparameter.fromgood_handlers.initimportNameInitHandlerclassPerson:__init__=NameInitHandler(names=('name','age','apparel','thoughts'))Default values for these can be provided as a dict in thedefaultsparameter.fromgood_handlers.initimportNameInitHandlerclassPerson:__init__=NameInitHandler(names=('name','age','apparel','thoughts'),defaults={'apparel':'Pajamas','thoughts':'Nothing at the moment...'})UnderscoreInitHandleris a type ofNamedInitHandlerthat appends an underscore_to each name before setting it in the instance.DunderInitHandleradds a dunder, or a double-underscore__before each nameString HandlersAnother case of redundant programming is string representations. The Good Library providesValueStringHandler, which prints the object name and the values of the given keys to show, andKeyValueStringHandler, which is likeValueStringHandler, but displays key=value pairs instead of just valuesfromgood_handlers.stringimportValueStringHandler,KeyValueStringHandlerclassPerson1:"""Docstring for Person"""def__init__(self,name,age):"""Initializes instance"""self.name=nameself.age=age__repr__=ValueStringHandler(('name','age'))classPerson2:"""Docstring for Person2"""def__init__(self,name,age):"""Initializes instance"""self.name=nameself.age=age__repr__=KeyValueStringHandler(('name','age'))john1=Person1('John Numberone',21)john2=Person2('John Numbertwo',28)print(john1)# prints 'Person1(\'John Numberone\', 21)'print(john2)# prints 'Person2(name=\'John Numbertwo\', age=28)'