Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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)
like image 780
user3080029 Avatar asked Aug 08 '14 13:08

user3080029


2 Answers

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.

like image 83
Matteo Italia Avatar answered Oct 25 '22 23:10

Matteo Italia


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'>
like image 20
flau Avatar answered Oct 25 '22 23:10

flau