Python 3中使用functools.lru_cache:装饰公共还是私有函数更优?
functools.lru_cache? Great question—your intuition to decorate the public function is spot-on for most cases like the one you shared! Let’s break down the "why" and the key differences between decorating public vs. private functions.
First: The Short Answer for Your Scenario
You should decorate my_public_function with lru_cache. Since your public function only forwards arguments to the private function and returns its result, caching at the public level lets you skip the entire function call chain for repeated inputs. No need to even invoke _my_private_function once the result is cached—this is the most efficient approach here.
Here’s what that looks like in code:
from functools import lru_cache @lru_cache(maxsize=None) def my_public_function(a, b, c) -> int: rv = _my_private_function(a, b, c) return rv def _my_private_function(a, b, c) -> int: return a + b + c
Key Differences Between Caching Public vs. Private Functions
Let’s dive into when each approach makes sense:
Decorating the Public Function
- Cache hits skip all downstream logic: When a repeated input comes in, the cache returns the result immediately—no call to the private function, no extra processing. This is ideal when your public function doesn’t have mandatory per-invocation logic (like parameter validation that depends on external state, or real-time logging that must run every time).
- Simpler cache scope: The cache is tied directly to the public API your users interact with. If you later modify the public function’s logic (e.g., add a transformation to the private function’s result), the cache will automatically use the updated logic for new inputs.
- Lower overhead: Avoids the extra function call to the private function on cache hits, which adds up for high-frequency calls.
Decorating the Private Function
- Shared cache across multiple callers: If your private function is used by multiple public functions (or other internal code), caching it lets all those callers reuse the same cached results. For example:
Here, both public functions benefit from the same cache for the private function’s inputs, avoiding redundant calculations.from functools import lru_cache def my_public_function(a, b, c) -> int: return _my_private_function(a, b, c) def my_other_public_function(x, y, z) -> int: return _my_private_function(x, y, z) * 2 @lru_cache(maxsize=None) def _my_private_function(a, b, c) -> int: return a + b + c - Public function logic runs every time: Even if the private function’s result is cached, the public function will still execute its own code (like argument parsing or logging) on every call. This is only desirable if that logic must run for every invocation, regardless of whether the private function’s result is cached.
Final Takeaway
For your specific example (public function is just a wrapper with no extra mandatory logic), decorating the public function is the best choice—it maximizes performance by cutting off unnecessary execution as early as possible. If your private function is shared across multiple callers, though, caching the private function becomes more useful to avoid duplicating cached results.
内容的提问来源于stack exchange,提问作者Jeremy Jones

