user3080029
user3080029

Reputation: 563

What happens when a function returns its own name in python?

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

What is the meaning of the last line in the code?

EDIT:

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)

Upvotes: 18

Views: 2604

Answers (4)

flau
flau

Reputation: 1380

Since all functions in Python are created as objects, it returns a reference to the function.

It may be passed into another function later in the code or called with parameters as you could with any function.

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)

Prints:

hello
<type 'function'>

Upvotes: 11

Cruncher
Cruncher

Reputation: 7812

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

settrace allows you to pass a function to use as a debugger. Every time a new scope is entered, the function you passed is called. It needs to return a function that should be used for debugging inside that scope.

Since the writer of that code, wanted to always use the same function, the function returns itself.

Relevant bit from the link:

The trace function is invoked (with event set to 'call') whenever a new local scope is entered; it should return a reference to a local trace function to be used that scope, or None if the scope shouldn’t be traced.

The local trace function should return a reference to itself (or to another function for further tracing in that scope), or None to turn off tracing in that scope.

Upvotes: 7

Matteo Italia
Matteo Italia

Reputation: 126777

A function is an object like anyone else, so there's no problem in returning itself. For example, it allows repeated calling on the same line:

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

Edit: sys.settrace sets the global tracing function, that is invoked every time a local scope is entered to ask for a local tracing function. Here it returns itself, to handle all the tracing in the same function.

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

Upvotes: 18

ojblass
ojblass

Reputation: 21620

It returns a function object. I am curious if you found this in live code and what the use case might be.

Upvotes: 3

Related Questions