当函数在Python中返回自己的名字时会发生什么?

18 投票
4 回答
2566 浏览
提问于 2025-04-18 16:33
def traceit(frame, event, trace_arg):
    global stepping

    if event == 'line':
        if stepping or frame.f_lineno in breakpoints:
            resume = False
            while not resume:
                print(event, frame.f_lineno, frame.f_code.co_name, frame.f_locals)
                command = input_command()
                resume = debug(command, frame.f_locals)
    return traceit
def remove_html_markup(s):
    tag   = False
    quote = False
    out   = ""

    for c in s:
        if c == '<' and not quote:
            tag = True
        elif c == '>' and not quote:
            tag = False
        elif c == '"' or c == "'" and tag:
            quote = not quote
        elif not tag:
            out = out + c
    return out

def main():
    print (remove_html_markup('xyz'))
    print (remove_html_markup('"<b>foo</b>"'))
    print (remove_html_markup("'<b>foo</b>'"))

# globals
breakpoints = {9: True}
stepping = False

def debug(command, my_locals):
    global stepping
    global breakpoints

    if command.find(' ') > 0:
        arg = command.split(' ')[1]
    else:
        arg = None

    if command.startswith('s'):     # step
        stepping = True
        return True
    elif command.startswith('c'):   # continue
        stepping = False
        return True
    elif command.startswith('q'):   # quit
        sys.exit(0)
    else:
        print ("No such command", repr(command))

    return False

commands = ['s', 's', 's', 'q']

def input_command():
    #command = raw_input("(my-spyder) ")
    global commands
    command = commands.pop(0)
    return command

def traceit(frame, event, trace_arg):
    global stepping

    if event == 'line':
        if stepping or frame.f_lineno in breakpoints:
            resume = False
            while not resume:
                print(event, frame.f_lineno, frame.f_code.co_name, frame.f_locals)
                command = input_command()
                resume = debug(command, frame.f_locals)
    return traceit

# Using the tracer
sys.settrace(traceit)
main()
sys.settrace(None)

代码最后一行是什么意思?

补充说明:

4 个回答

3

它返回的是一个函数对象。我很好奇你是在实际代码中发现这个的,可能有什么用处呢?

7

https://docs.python.org/2/library/sys.html#sys.settrace

settrace 这个功能让你可以传入一个函数,用作调试器。每当进入一个新的作用域时,你传入的那个函数就会被调用。这个函数需要返回一个在那个作用域内用于调试的函数。

因为写这段代码的人想要始终使用同一个函数,所以这个函数返回的就是它自己。

链接中的相关内容:

每当进入一个新的本地作用域时,跟踪函数会被调用(事件设置为'call');它应该返回一个本地跟踪函数的引用,用于在那个作用域内进行跟踪,如果不需要跟踪这个作用域,就返回 None。

本地跟踪函数应该返回对它自己的引用(或者返回另一个函数,以便在那个作用域内进一步跟踪),或者返回 None 来关闭这个作用域的跟踪。

11

因为Python中的所有函数都是以对象的形式存在,所以它返回的是对这个函数的引用。

这个引用可以在代码的后面传递给另一个函数,或者像调用任何函数一样,带上参数来调用它。

def a(str):
    print str
b = a # Assign an instance of a to b
b('hello') # Call b as if it were a

print type(b)

输出结果是:

hello
<type 'function'>
18

一个函数就像其他对象一样,所以它可以返回自己,这没有问题。比如,这样可以在同一行上重复调用:

traceit("abc", "def", None)("ghi", "jkl", 3)("mno", "pqr", 4.3)

补充说明:sys.settrace 是用来设置全局跟踪函数的,每当进入一个局部作用域时,它会被调用,以请求一个局部跟踪函数。在这里,它返回自己,以便在同一个函数中处理所有的跟踪。

详细信息请查看 https://docs.python.org/2/library/sys.html#sys.settrace

撰写回答