import copy import functools from typing import Callable, TypeVar T = TypeVar("T", bound=Callable) def copydefaults(f: T) -> T: original_defaults = f.__defaults__ @functools.wraps(f) def newf(*args, **kwargs): f.__defaults__ = copy.deepcopy(original_defaults) return f(*args, **kwargs) return newf @copydefaults def f(key, d={}): d[key] = 42 return d print(f("foo")) # {'foo': 42} print(f("bar")) # {'bar': 42}