Class Decorator
Syntactic Sugar
@decorator_a
@decorator_b
class A:
pass
semantically equivalent:
class A:
pass
A = decorator_a(decorator_b(A))
Usage: Decorator is Class
A class decorator is defined as follows:
from functools import wraps
class Decorator:
def __init__(self, func):
print('create instance')
self.func = func
@wraps(func)
def __call__(self, *args, **kwargs):
print('working here')
return self.func(*args, **kwargs)
@Decorator
def func(arg1, arg2):
return f'{arg1=}, {arg2=}'
>>> func('A', 'B')
create instance
working here
"arg1='A', arg2='B'"
Usage: Decorator for Class
A decorator for classes is defined as follows:
def decorator(cls):
cls.num_of_animals = 10
return cls
@decorater
class A:
pass
>>> a_obj = A()
>>> A.num_of_animals
10
Example: Singleton Instance
Define a class with a singleton instance:
def singleton(cls):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return getinstance
@singleton
class MyClass:
pass
>>> c1 = MyClass()
>>> c2 = MyClass()
>>> assert c1 == c2
>>> assert c1 is c2
Example: Implement Interfaces
Declare that a class implements a particular (set of) interface(s).
def provides(*interfaces):
"""
An actual, working, implementation of provides for
the current implementation of PyProtocols.
Not particularly important for the PEP text.
"""
def provides(typ):
declareImplementation(typ, instancesProvide=interfaces)
return typ
return provides
class IBar(Interface):
"""Declare something about IBar here"""
pass
@provides(IBar)
class Foo(object):
"""Implement something here..."""
pass