【问题标题】:Limit a method to be called only through another method?限制一个方法只能通过另一个方法调用?
【发布时间】:2012-12-08 17:16:20
【问题描述】:

假设我有两种方法first_methodsecond_method 如下。

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!")

如何检查(什么条件)第一种方法正在调用第二种方法并根据该方法处理该方法?

【问题讨论】:

  • 你有一些选择......要么使用闭包、装饰器,要么传递某种状态对象——如果对象处于无效状态,那么它可以引发SomeError
  • 这个[stackoverflow.com/questions/1095543/… 帖子讨论了同样的问题。希望对您有所帮助。

标签: python django methods call


【解决方案1】:

为什么不在第一个方法中定义第二个方法,这样它就不会被直接调用。

示例:

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])

【讨论】:

  • 更好的是,根本不把它定义为一个函数,直接把它的功能放在first_method里面。
  • @BrenBarn,是的,我同意,当我坐下来重新审视它时。
【解决方案2】:

您可以查看inspect module 中的一些堆栈函数。

但是,您所做的可能是个坏主意。尝试强制执行此类事情根本不值得麻烦。只需记录不应该直接调用第二种方法,给它起一个带前导下划线的名称(_secret_second_method 或其他),然后如果有人直接调用它,那是他们自己的问题。

或者,不要将其作为一个单独的方法,而是将代码放在first_method 中。如果它从不从一个地方调用,为什么你需要让它成为一个单独的函数?在这种情况下,它也可能是第一种方法的一部分。

【讨论】:

  • 如果有人直接调用它会发生什么?
  • @Amyth:然后出了点问题,当您执行文档中不允许执行的操作时,通常会发生这种情况。
  • 我使用一种命令模式来实现撤销/重做。这种技巧在这里非常有用(在开发时),以确保我的模型更改函数只能从命令中调用,因此它们可以撤消。
【解决方案3】:

这里是一个示例,与 Django 无关,如何获取调用者方法框架(该框架中有很多信息):

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}')

基本上,您可以使用sys._current_frames()[thread.get_ident()] 获取帧链表头(每个调用者的帧),然后查找您想要的任何运行时信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-16
    • 2015-12-01
    • 2016-07-02
    相关资源
    最近更新 更多