Reputation: 4483
My idea is to build some kind of caching mechanism for functions. To that end, I need to determine if a function needs to be evaluated. The result of a function depends - for the sake of this example - on its parameters and the actual code of the function. There may be calls to other functions inside the function. Therefore, only the fully inlined code of the function is a useful "value" for determining whether a function needs to be reevaluated.
Is there a good way to get this fully inlined code of a function in python?
Upvotes: 0
Views: 51
Reputation: 87134
Although it's possible in Python, code is not generally in a state of flux if you're concerned that it might change behind your back. There might be something in the dis
module that could help you.
Otherwise you could use memoization to cache function results by mapping them to their parameters. You could use the @functools.lru_cache()
decorator, but writing a decorator to do that is pretty easy. See What is memoization and how can I use it in Python?
Apart from mutating code (which might even affect pure functions), the value of any function that relies on changing data is also indeterminate, e.g. some function that returns the latest stock price for a company. Memoization would not help here, nor would producing a function code signature/hash to detect changes in code.
Upvotes: 1
Reputation: 281683
Not possible. The "fully inlined code" of a Python function isn't a well-defined concept, for multiple reasons.
First, almost anything a Python function refers to can be redefined at runtime, which invalidates ahead-of-time inlining. You can even replace built-ins like print
.
Second, even with no such rebinding, it is impossible to "fully inline" a recursive or indirectly recursive function.
Third, a function can and almost always will invoke code dynamically based on the provided parameters. def f(x): return x.something()
requires a concrete value of x
to determine what something
is. Even something like def f(x, y): return x + y
dynamically invokes an __add__
or __radd__
callback that can't be determined until the actual values of x
and y
are known.
Fourth, Python functions can invoke C code, which cannot be inlined at Python level.
Finally, even if all the problems with "fully inlining" a function didn't exist, a "fully inlined" version of a function still wouldn't be enough. There is no general way to determine if a Python function performs state mutation, or depends on mutable state that has been mutated, both of which are major issues for caching.
Upvotes: 4