When are symbols for functions bound in Python? Is a declaration possible?
Suppose we have a hash table that displays strings in a function. In my example, I will name it COMMANDS
. If I put a definition for some function (by calling it cmd_add
) after a hash table that maps it to a string, and then I try to call it, I get an error:
COMMANDS = {'add': cmd_add}
def cmd_add():
print 'ADD'
COMMANDS['add']()
# NameError: name 'cmd_add' is not defined
Now, note that if I just step through the function definition before the definition COMMANDS
, this is just fine:
def cmd_add():
print 'ADD'
COMMANDS = {'add': cmd_add}
COMMANDS['add']()
# NO ERROR!
Why is this so? Is there something about bindings with Python that I don't understand?
source to share
Remember that Python is a dynamic language, although cmd_add is a function reference in your source, and nothing prevents it from referring to another object at different times.
Python will create the binding because the interpreter passes the string where the function is defined and will refer to that function until you remove the link or reinstall it to something else.
source to share
Well, the module is interpreted from top to bottom. In your first snippet, it hasn't seen it yet cmd_add
, so it throws outNameError
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 can get fancy and wrap with a cmd_add
decorator that registers it inCOMMANDS
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']()
source to share