0

Say i have two methods first_method and second_method as follows.

def first_method(some_arg):
    """
    This is the method that calls the second_method
    """

    return second_method(some_arg[1], some_arg[2])


def second_method(arg1, arg2):
    """
    This method can only be called from the first_method
    or it will raise an error.
    """

    if (some condition):
        #Execute the second_method
    else:
        raise SomeError("You are not authorized to call me!")

How can i check (what condition(s)) that second method is being called by the first method and process the method according to that ?

Amyth
  • 32,527
  • 26
  • 93
  • 135
  • 1
    You've got some options...either use closures, decorators, or pass along some sort of state object - if the object is in an invalid state, then it can raise `SomeError`. – Makoto Dec 21 '12 at 05:49
  • 1
    This[http://stackoverflow.com/questions/1095543/get-name-of-calling-functions-module-in-python] post discuss the same question. Hope that helps. – Somesh Dec 21 '12 at 07:10

3 Answers3

4

Why don't you define the second method within first method, so that its not exposed to be called directly.

example:

def first_method(some_arg):
    """
    This is the method that calls the second_method
    """
    def second_method(arg1, arg2):
        """
        This method can only be called from the first_method
        hence defined here
        """

        #Execute the second_method


    return second_method(some_arg[1], some_arg[2])
Rohan
  • 52,392
  • 12
  • 90
  • 87
1

You could look at some of the stack functions in the inspect module.

However, what you are doing is probably a bad idea. It simply isn't worth the trouble to try to enforce this sort of thing. Just document that the second method is not supposed to be called directly, give it a name with a leading underscore (_secret_second_method or whatever), and then if anyone calls it directly it's their own problem.

Alternatively, just don't make it a separate method and put the code right in first_method. Why do you need to make it a separate function if it's never called except from one place? In that case it might as well be part of the first method.

BrenBarn
  • 242,874
  • 37
  • 412
  • 384
  • if someone calls it directly then what happens ? – Amyth Dec 21 '12 at 05:47
  • 1
    @Amyth: Then something goes wrong, which is what often happens when you do something the documentation says not to do. – BrenBarn Dec 21 '12 at 05:51
  • I use a kind of command pattern to implement undo/redo. This kind of trick here is very useful (while developing) to ensure that my model-changing functions are only called from within commands, so they can be undoable. – jdm May 10 '13 at 11:01
1

Here is example, not particularly related to Django, of how to obtain caller method frame (there is a lot of info in that frame):

import re, sys, thread

def s(string):
    if isinstance(string, unicode):
        t = str
    else:
        t = unicode
    def subst_variable(mo):
        name = mo.group(0)[2:-1]
        frame = sys._current_frames()[thread.get_ident()].f_back.f_back.f_back
        if name in frame.f_locals:
            value = t(frame.f_locals[name])
        elif name in frame.f_globals:
            value = t(frame.f_globals[name])
        else:
            raise StandardError('Unknown variable %s' % name)
        return value
    return re.sub('(#\{[a-zA-Z_][a-zA-Z0-9]*\})', subst_variable, string)

first = 'a'
second = 'b'
print s(u'My name is #{first} #{second}')

Basically you may use sys._current_frames()[thread.get_ident()] to obtain head of frame linked list (frame per caller) and then lookup for whatever runtime info you want.

Vladimir
  • 9,913
  • 4
  • 26
  • 37