I'm having trouble applying a decorator to an imported function. Suppose I have the following foo.py module: # contents of foo.py def bar(): return "hello" I now want to import bar from it and apply the lru_cache decorator, so in my main file I do this: from functools import lru_cache import foo def main(): # caching foo.bar works fine for _ in range(2): if hasattr(foo.bar, "cache_info"): print("bar is already cached") else: print("caching bar") setattr(foo, "bar", lru_cache(foo.bar)) if __name__ == "__main__": main() which produces, as expected, the following output: caching bar bar is already cached However, I don't want to import the whole foo module, so now I only import bar and rely on sys.modules to find out where bar comes from. Then main.py becomes: from functools import lru_cache import sys from foo import bar def main(): for _ in range(2): if hasattr(bar, "cache_info"): print("bar is already cached") else: print("caching bar") setattr(sys.modules[__name__], "bar", lru_cache(bar)) if __name__ == "__main__": main() Again, this produces the wanted output: caching bar bar is already cached But now I want my decorating process to be reusable in several modules, so I write it as a function in file deco.py: from functools import lru_cache import sys def mydecorator(somefunction): for _ in range(2): if hasattr(somefunction, "cache_info"): print(f"{somefunction.__name__} is already cached") else: print(f"caching {somefunction.__name__}") setattr(sys.modules[somefunction.__module__], "bar", lru_cache(somefunction)) And so main.py becomes: import sys from foo import bar from deco import mydecorator def main(): mydecorator(bar) if __name__ == "__main__": main() This time the decoration fails; the output becomes: caching bar caching bar # <- wrong; should be cached already How do I correct my code? Continue reading...