Understanding Python Decorators: Concepts, Usage, and Advanced Patterns
This article explains Python decorators—from basic closure equivalents to factory‑style registry usage—showing how they register modules, modify function behavior, handle parameters, support multiple decorators, and can decorate both functions and classes, all with clear code examples.
Decorators are a fundamental Python feature that can be confusing for beginners but are widely used in medium and large projects to enhance functions and classes.
The article starts with an engineering example from the Featdepth model source code, showing how a Registry class is used to store modules in a dictionary and retrieve them via a model name.
from mono.model.registry import MONO
from mmcv import Config
def main():
args = parse_args()
cfg = Config.fromfile(args.config)
model_name = cfg.model['name'] # returns model name string
model = MONO.module_dict[model_name](cfg.model)
...
if __name__ == '__main__':
main()The Registry class defines module_dict and a register_module decorator that registers a class under its name, effectively implementing the factory pattern.
class Registry(object):
def __init__(self, name):
self._name = name
self._module_dict = dict()
@property
def name(self):
return self._name
@property
def module_dict(self):
return self._module_dict
def _register_module(self, module_class):
...
def register_module(self, cls):
self._register_module(cls)
return cls
MONO = Registry('mono')When a module file imports @MONO.register_module before a class definition, the class is automatically added to MONO.module_dict , allowing later instantiation with MONO.module_dict[model_name](cfg.model) .
The article then distills five key points about decorators:
Decorators are syntactic sugar for closures; they receive a function and return a new function.
The decorator code runs at definition time, not at each call of the decorated function.
Multiple decorators are applied from the bottom up during definition and from the top down during execution.
Decorators can accept arguments and must add an extra wrapper layer to pass through *args and **kwargs .
Both functions and classes can be decorated; a class decorator returns a new class, and a decorator implemented as a class uses its __call__ method.
Each point is illustrated with concise code snippets demonstrating simple decorators, decorators with parameters, and class‑based decorators.
def funcA(func):
def funcB():
print('funcA')
func()
return funcB
@funcA
def funcC():
print('funcC')and more advanced examples with arguments and class decorators are provided.
Overall, the article offers a practical guide to mastering Python decorators, from basic closure equivalents to complex factory‑style registrations used in real projects.
Python Programming Learning Circle
A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.