Python metaprogramming

python #metaprogramming

Examples from my codebases https://github.com/barisozmen/python-cookbook/blob/main/metaclasses.py ```python from clisupport import gracefulkeyboardinterrupt, debuggeron_error

class SingletonMetaclass(type): instances = {} def _call(cls, args, *kwargs): if cls not in cls.instances: cls.instances[cls] = super().call_(args, *kwargs) return cls.instances[cls]

class GracefulInterruptMetaclass(type): def new(cls, name, bases, attrs): # Wrap all public methods with gracefulkeyboardinterrupt for key, value in attrs.items(): if callable(value) and not key.startswith(''): attrs[key] = gracefulkeyboardinterrupt(value) return super().new_(cls, name, bases, attrs)

class DebuggerOnErrorMetaclass(type): def new(cls, name, bases, attrs): for key, value in attrs.items(): if callable(value) and not key.startswith(''): attrs[key] = debuggeronerror(value) return super().new_(cls, name, bases, attrs)

class LoggedMetaclass(type): """Metaclass that logs all method calls for a class""" def new(cls, name, bases, attrs): # Wrap callable methods with logging for key, value in attrs.items(): if callable(value) and not key.startswith(''): attrs[key] = cls.logcall(value) return super().new(cls, name, bases, attrs)

@staticmethod
def log_call(func):
    def wrapper(*args, **kwargs):
        print(f'Calling: {func.__name__}')
        result = func(*args, **kwargs)
        print(f'Finished: {func.__name__}')
        return result
    return wrapper

class StaticMethodsByDefault(type): def new(cls, name, bases, attrs): # Make all methods static by default, except special methods for key, value in attrs.items(): if callable(value) and not key.startswith(''): attrs[key] = staticmethod(value) return super().new__(cls, name, bases, attrs)


https://github.com/barisozmen/python-cookbook/blob/main/cli_support.py
```python
import os
import sys
from functools import wraps


def graceful_keyboard_interrupt(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except KeyboardInterrupt:
            print("\n\nKeyboard interrupt detected. Exiting...")
            print("\nGoodbye! 👋\n")
            sys.exit(1)
    return wrapper


def debugger_on_error(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as e:
            import pdb; pdb.set_trace()
            raise e
    return wrapper

https://github.com/barisozmen/python-cookbook/blob/main/singletons.py ```python from metaclasses import SingletonMetaclass

class Counter(metaclass=SingletonMetaclass): def init(self): self.count = 0

@property
def next_id(self):
    self.count += 1
    return self.count

class Config(metaclass=SingletonMetaclass): def init(self): self._settings = {}

def set(self, key, value):
    self._settings[key] = value

def get(self, key, default=None):
    return self._settings.get(key, default) 

Linked from