简体   繁体   中英

When do symbols for functions bind in Python? Is forward declaration possible?

Suppose we have a hash table that maps strings to functions. In my example I'll call it COMMANDS . If I place the definition for some function (let's call it cmd_add ) after the hash table that maps it to a string, and then I attempt to invoke it, I get an error:

COMMANDS = {'add': cmd_add}

def cmd_add():
  print 'ADD'

COMMANDS['add']()

# NameError: name 'cmd_add' is not defined

Now notice that if I simply move the function definition to before the definition of COMMANDS , it works out just fine:

def cmd_add():
  print 'ADD'

COMMANDS = {'add': cmd_add}

COMMANDS['add']()

# NO ERROR!

Why is this true? Is there something about Python binding that I do not understand?

Well, the module is interpreted from top to bottom. In your first snippet, it hasn't seen cmd_add yet, so it throws a NameError

You can do it like your second snippet, or something like this:

COMMANDS = {}

def cmd_add():
    print 'ADD'

def register_commands():
    COMMANDS.update({'add': cmd_add})

register_commands()

Or you could get fancy and wrap cmd_add with a decorator that registers it in the COMMANDS

COMMANDS = {}

# command decorator to register command functions
class command(object):
    def __init__(self, name):
        self.name = name
    def __call__(self, func):
        COMMANDS[self.name] = func
        return func

@command('add')
def cmd_add():
    print 'ADD'

COMMANDS['add']()

Remember that Python is a dynamic language, even though cmd_add is a reference to a function in your source there is nothing stopping it from referring to a different object at different times.

Python will creating the binding as the interpreter passes the line where the function is defined and it will reference that function until you delete the reference or rebind it to something else

在Python脚本中,表达式从上到下进行计算,因此定义函数之前不能引用它。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM