Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 545
apc Avatar asked Sep 12 '26 21:09

apc


1 Answers

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']()
like image 110
FogleBird Avatar answered Sep 16 '26 15:09

FogleBird



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!