Reputation: 505
I'm wondering if anyone can think up a way to check if a function needs to return a meaningful value in Python. That is, to check whether the return value will be used for anything. I'm guessing the answer is no, and it is better to restructure my program flow. The function in question pulls its return values from a network socket. If the return value is not going to get used, I don't want to waste the resources fetching the result.
I tried already to use tracebacks to discover the calling line, but that didn't work. Here's an example of what I had in mind:
>>> def func():
... print should_return()
...
>>> func()
False
>>> ret = func()
True
The function "knows" that its return value is being assigned.
Here is my current workaround:
>>> def func(**kwargs):
... should_return = kwargs.pop('_wait', False)
... print should_return
...
>>> func()
False
>>> ret = func(_wait=True)
True
Upvotes: 9
Views: 2465
Reputation: 3555
i have some code that kinda works using inspect module, but it might be prone to break like others mention.
inspect.stack()[1].frame.f_code.co_names[-1]
will be holding the function name when user didn't assign return value to anything, when user assign to var with name XXX, this var will hold XXX. Code comparing this vs the function name to decide whether user assign the return value to any var
import inspect
def func():
tmp = inspect.stack()[1].frame.f_code.co_names[-1]
should_return = tmp != 'func'
print("execute") # execute something
# if should_return False, end here without fetching result
if should_return:
print("fetching result, user assign to {}".format(tmp))
# fetching result and return the result here
>>> func()
execute
>>>
>>> xxx=func()
execute
fetching result, user assign to xxx
>>>
Upvotes: 0
Reputation: 35453
One approach might be to return an object with a __del__
method that relies on the garbage collector removing the unused value some time in the future.
Note that it won't happen immediately; it might not even happen at all :)
Upvotes: 1
Reputation: 11940
You might consider returning a future, or 'promise'. That is, return another function that, when executed, performs the necessary work to actually determine the result. I seem to be thinking that you want lazy evaluation, which is "evaluate only what you need" (more or less), rather than your question, which confusingly asks: "Evaluate only if it returns a value, which might be needed".
Upvotes: 0
Reputation: 397
All functions in Python always return. If you don't explicitly return, functions return None.
===========
def func(): while True: pass
This function does not return.
There is no way of determining if an arbitrary function will return. If you can, you have solved the Turing problem.
Upvotes: -1
Reputation: 90842
The very second line of the body of import this
says it all: "explicit is better than implicit". In this case, if you provide an optional argument, the code will be more obvious (and thus easier to understand), simpler, faster and safer. Keep it as a separate argument with a name like wait
.
While with difficulty you could implement it magically, it would be nasty code, prone to breaking in new versions of Python and not obvious. Avoid that route; there lieth the path unto madness.
Upvotes: 5
Reputation: 11940
All functions return a value when they complete.
If you're asking if they should return at all, then you are actually asking about The Halting Problem
Upvotes: 3