Violet
Violet

Reputation: 505

Check if there's something "waiting for" the return value of a function

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

Answers (6)

Skycc
Skycc

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

kolypto
kolypto

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

Arafangion
Arafangion

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

Nickle
Nickle

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

Chris Morgan
Chris Morgan

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

Arafangion
Arafangion

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

Related Questions