José Luis
José Luis

Reputation: 3933

Python, change function behavior depending on caller, is it possible?

In this Python code snippet:

def get_something():
    return something

def do_staff():
    value = get_something()
    doit(value)

def test():
    # ?????
    doStaff()

What is the best way to change the value returned by get_something depending on if was called through test or not? The only restriction is that I don't want to modify do_staff

Upvotes: 0

Views: 2977

Answers (2)

Henry Keiter
Henry Keiter

Reputation: 17168

Answering the Question You Asked

You either want an optional argument to change the behavior of the function. This means you also need an optional argument in do_staff, since the real question here is how to tell get_something where do_staff was called from (test or elsewhere):

def get_something(test=False):
    if test:
        return something + test_var
    return something

def do_staff(test=False):
    value = get_something(test=test)
    return doit(value)

def test():
    return do_staff(test=True)

If you really, really are averse to modifying do_staff for some reason, you'll have to look through the stack to see if the test method is up there, as someone mentioned in the comments--but that gets ugly really quickly. Otherwise, the only way to tell how a function was called is to pass an indicator through.

Actually Solving Your Problem

From context, though, I think what you really want is to know how to test this thing without having to modify too much code between test/production environments. In that case, I'd suggest a totally different approach: rather than trying to see if you were called from a certain place, just define/import a is_debug_on variable and use that.

is_debug_on = False

def get_something():
    if is_debug_on:
        pass # Do testing stuff, print statements, etc.
    return something # Do normal stuff.

def do_staff():
    value = get_something()

def test():
    is_debug_on = True
    do_staff()
    is_debug_on = False

Obviously this is cleaner if you can put it all inside a class, or use the logging package, or so forth, but this is the basic idea. You can test all your code this way and not have to remove anything when you move to production, because debug mode will be turned off. Bonus: when things go wrong in production, you'll be able to turn debug back on and (hopefully) get some useful information right away!

Upvotes: 2

Santa
Santa

Reputation: 11547

Optional argument?

def get_something(from_test=False):
    if from_test:
        return something_test
    else:
        return something

def test():
    get_something(True)

Upvotes: 1

Related Questions