from functools import wraps installed_packages = [] def install_package(pkg): if pkg not in installed_packages: installed_packages.append(pkg) print(f"Installed: {pkg}") else: print(f"Already installed: {pkg}") def needs_packages(packages): def inner_decorator(function): @wraps(function) def execution_wrapper(*args, **kwargs): [install_package(package) for package in packages] return function(*args, **kwargs) return execution_wrapper return inner_decorator @needs_packages(['vim', 'calc']) def add(z1, z2): return z1 + z2 @needs_packages(['calc', 'sed']) def sub(z1, z2): return z1 - z2 @needs_packages(['calc']) def bla(z1, z2): return z1 / z2 print(add(1, 2)) print(sub(1, 2)) print(bla(1, 2))