6.14. Decorate Class
mydecorator
is a decorator nameMyClass
is a class name
Syntax:
>>> @mydecorator
... class MyClass:
... ...
Is equivalent to:
>>> MyClass = mydecorator(MyClass)
6.14.1. Syntax
mydecorator
is a decorator nameMyClass
is a class name
>>> def decorator(cls):
... class Wrapper(cls):
... def __new__(cls, *args, **kwargs):
... ...
... return Wrapper
>>>
>>>
>>> def decorator(cls):
... def wrapper(*args, **kwargs):
... instance = cls.__new__(cls, *args, **kwargs)
... return instance
... return wrapper
>>>
>>>
>>> @decorator
... class MyClass:
... ...
>>>
>>>
>>> my = MyClass()
6.14.2. Example
>>> def run(cls):
... def wrapper(*args, **kwargs):
... instance = cls.__new__(cls, *args, **kwargs)
... return instance
... return wrapper
>>>
>>>
>>> @run
... class User:
... def say_hello(self, name):
... return f'My name... {name}'
>>>
>>>
>>> mark = User()
>>> mark.say_hello('José Jiménez')
'My name... José Jiménez'
6.14.3. Use Case - 1
Logger
>>> import logging
>>>
>>>
>>> def logger(cls):
... class Wrapper(cls):
... logger = logging.getLogger(cls.__name__)
... return Wrapper
>>>
>>>
>>> @logger
... class User:
... pass
>>>
>>>
>>> print(User.logger)
<Logger User (WARNING)>
6.14.4. Use Case - 2
Since
>>> from datetime import datetime, timezone
>>>
>>>
>>> def since(cls):
... class Wrapper(cls):
... _since = datetime.now(timezone.utc)
... return Wrapper
>>>
>>>
>>> @since
... class User:
... pass
>>>
>>>
>>> print(User._since)
datetime.datetime(1969, 7, 21, 2, 56, 15, tzinfo=datetime.timezone.utc)
6.14.5. Use Case - 3
Singleton Func
>>> def singleton(cls):
... def wrapper(*args, **kwargs):
... if not hasattr(cls, '_instance'):
... instance = object.__new__(cls, *args, **kwargs)
... setattr(cls, '_instance', instance)
... return getattr(cls, '_instance')
... return wrapper
>>>
>>>
>>> @singleton
... class DatabaseConnection:
... def connect(self):
... print(f'Connecting...')
>>>
>>>
>>> a = DatabaseConnection() # Will create instance
>>> a.connect()
Connecting...
>>>
>>> b = DatabaseConnection() # Will reuse instance
>>> b.connect()
Connecting...
6.14.6. Use Case - 4
Singleton Cls
>>> def singleton(cls):
... class Wrapper(cls):
... def __new__(cls, *args, **kwargs):
... if not hasattr(cls, '_instance'):
... instance = object.__new__(cls, *args, **kwargs)
... setattr(cls, '_instance', instance)
... return getattr(cls, '_instance')
... return Wrapper
>>>
>>>
>>> @singleton
... class DatabaseConnection:
... def connect(self):
... print(f'Connecting...')
>>>
>>>
>>> a = DatabaseConnection() # Will create instance
>>> a.connect()
Connecting...
>>>
>>> b = DatabaseConnection() # Will reuse instance
>>> b.connect()
Connecting...
6.14.7. Use Case - 5
>>> from datetime import datetime, timezone
>>> from uuid import uuid4
>>>
>>>
>>> def trace(cls):
... class Wrapper(cls):
... __name__ = cls.__name__
... __doc__ = cls.__doc__
... __qualname__ = cls.__qualname__
...
... def __init__(self, *args, **kwargs):
... self._uuid = str(uuid4())
... self._log = logging.getLogger(cls.__name__)
... self._since = datetime.now(timezone.utc)
... super().__init__(*args, **kwargs)
...
... def _life_duration(self):
... now = datetime.now(timezone.utc)
... duration = now - self._since
... return duration.total_seconds()
...
... return Wrapper
>>> @trace
... class User:
... pass
>>>
>>>
>>> mark = User()
>>> melissa = User()
>>> mark._uuid
'8b383148-1dd8-4eca-aaa2-6e1deba7ff46'
>>>
>>> melissa._uuid
'0a598bb9-cecc-4d3f-82e1-33207ada09ab'
>>> mark._since
datetime.datetime(1961, 4, 12, 6, 7, 00, tzinfo=datetime.timezone.utc)
>>>
>>> melissa._since
datetime.datetime(1969, 7, 21, 2, 56, 15, tzinfo=datetime.timezone.utc)
>>>
>>>
>>> mark._life_duration()
85.035824
>>>
>>> melissa._life_duration()
76.601305
>>> mark._log
<Logger User (WARNING)>
>>> melissa._log
<Logger User (WARNING)>
>>>
>>>
>>> mark._log.warning('Some warning...')
Some warning...
>>>
>>> melissa._log.warning('Some warning...')
Some warning...