Package: decko
DeckoDecko is a decorator-based library designed for the following purposesSimplify the creation of decorators and reduce boilerplateChange the behavior of existing classes and function with minimal modificationsManage and monitor the state of instantiated decoratorsProvide a rich set of pre-made and tested decoratorsDecko is not dependent on any external libraries that are not included in the standard Python package.
However, one may choose to extend with external libraries such as numba to improve its performance.Updates / NewsSelf-contained decorators that can be used without creating aDeckoinstance is under development.In the most recent release, support for default keyword args is supported.
Additionally, support for@classmethod,@staticmethodand class instance method is also added.InstallInstall and update usingpip:pipinstall-UdeckoUninstallUninstall using pip:pipuninstalldeckoExampleDecko is a decorated-based module for debugging.
It also provides useful decorators to speed up programming and provides utility
function for easier decorator usage. Here is an examplefromsrc.deckoimportDeckoif__name__=="__main__":# Create decko instancedk=Decko(__name__)# Attach a profiling function@dk.profiledefcreate_list(n):returnlist(range(n))foriinrange(20):create_list(100000)# print profiled resultdk.print_profile()Decko also provides standalone decorators that can be applied immediately to your projects.
It also has built-in decorator functions to help developers quickly build debuggable custom
decorators. This allows developers to modify and extend code with minimal modifications to
the existing codebase.decoratorcreates function decorators that can be used to decorate both functions and
classes. Demo for creating class and function decorators is shown below.fromdeckoimportdeckoratorimporttimeimporttypingastdeftimer(func):"""An ordinary decorator.Will be used to check theperformance of decorate function"""definner(*args,**kwargs):start_time=time.time()output=func(*args,**kwargs)elapsed=time.time()-start_timeprint(f"Time elapsed:{elapsed}")returnoutputreturninner# Create decorator called "time_it" that accepts the following args# 1. Int value# 2. A callable object or a List@deckorator((int,float),(t.Callable,t.List))deftime_it(wrapped_function,interval,callback,*args,**kwargs):print(f"wrapped function:{wrapped_function.__name__}, interval:{interval},"f" args:{args}")# Check every 5 intervali=time_it.calledif(i+1)%interval==0:start_time=time.time()output=wrapped_function(*args,**kwargs)elapsed=time.time()-start_timecallback(elapsed,i+1)else:output=wrapped_function(*args,**kwargs)time_it.called+=1returnoutputtime_it.called=0@deckorator(is_class_decorator=True)defimmutable(wrapped_class,*args,**kwargs):defdo_freeze(slf,name,value):msg=f"Class{type(slf)}is immutable. "\f"Attempted to set attribute '{name}' to value: '{value}'"raiseAttributeError(msg)classImmutable(wrapped_class):"""A basic immutable class"""def__init__(self,*args,**kwargs):super().__init__(*args,**kwargs)setattr(Immutable,'__setattr__',do_freeze)returnImmutable(*args,**kwargs)@immutableclassSampleClass:def__init__(self,a,teemo):self.a=a@time_it(1,print)@classmethoddefmethod(cls):return"yee"if__name__=="__main__":deco_cls=SampleClass(10,20)deco_cls.method()test=SampleClass(20,40)try:deco_cls.a=50exceptAttributeError:print("class is immutable")print(deco_cls.a)FeaturesDecko detects and raises customized, informative errors such asDuplicateDecoratorError.
This helps in debugging and extending features with minimal modifications to the existing
codebase.fromdeckoimportDeckodk=Decko(__name__,debug=True)deflog_impurity(argument,before,after):print(f"Argument:{argument}modified. Before:{before}, after:{after}")defi_run_before(a,b,c,item):print(f"Run before func:{a},{b},{c},{item}")@dk.run_before(i_run_before)# This should not be allowed since it is a duplicate@dk.run_before(i_run_before)@dk.pure(callback=log_impurity)@dk.profiledefexpensive_func(a,b,c=1000000,item=[]):foriinrange(100):temp_list=list(range(c))item.append(temp_list)a+=20b+=atotal=a+breturntotalclassDummyClass:def__init__(self,item):self.item=item# @dk.pure(log_impurity)# @dk.profiledefset_item(self,item):self.item=itemdef__repr__(self):returnf'DummyClass:{self.item}'test=DummyClass(10)test.set_item(20)# Error raisedoutput=expensive_func(10,20,40)Decko raises informative error messages to help debug issues.
In later versions, features to define error callbacks with custom exceptions will be made.Traceback(mostrecentcalllast):File"path",line17,in<module>defexpensive_func(a,File"path",line522,inwrapperfn:t.Callable=self._decorate(self.run_before,fn)File"path",line334,in_decorateself.add_decorator_rule(decorator_func,func)File"path",line241,inadd_decorator_ruleself._add_function_decorator_rule(decorator_func,File"path",line213,in_add_function_decorator_ruleself._update_decoration_info(decorator_func,func,properties)File"path",line490,in_update_decoration_infoself.handle_error(f"Found duplicate decorator with identity: {func_name}",File"path",line325,inhandle_errorraiseerror_type(msg)src.decko.exceptions.DuplicateDecoratorError:Foundduplicatedecoratorwithidentity:__main__.expensive_funcLinksDocumentation:https://github.com/JWLee89/decko/wikiPyPI Releases:https://github.com/JWLee89/deckoSource Code:https://github.com/pallets/flask/