Когда символы для функций связываются в Python?Возможна ли предварительная декларация? - PullRequest
3 голосов
/ 19 марта 2012

Предположим, у нас есть хеш-таблица, которая отображает строки в функции. В моем примере я назову это COMMANDS. Если я помещаю определение для некоторой функции (назовем ее cmd_add) после хеш-таблицы, которая отображает ее в строку, а затем я пытаюсь вызвать ее, я получаю ошибку:

COMMANDS = {'add': cmd_add}

def cmd_add():
  print 'ADD'

COMMANDS['add']()

# NameError: name 'cmd_add' is not defined

Теперь обратите внимание, что если я просто переместу определение функции до определения COMMANDS, все будет работать нормально:

def cmd_add():
  print 'ADD'

COMMANDS = {'add': cmd_add}

COMMANDS['add']()

# NO ERROR!

Почему это правда? Есть ли что-то в привязке Python, чего я не понимаю?

Ответы [ 3 ]

3 голосов
/ 19 марта 2012

Ну, модуль интерпретируется сверху вниз.В вашем первом фрагменте он еще не видел cmd_add, поэтому он выбрасывает NameError

. Вы можете сделать это как свой второй фрагмент или что-то вроде этого:

COMMANDS = {}

def cmd_add():
    print 'ADD'

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

register_commands()

Или вы можете получить фантазию и обернуть cmd_add с помощью декоратора, который регистрирует его в 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']()
2 голосов
/ 19 марта 2012

Помните, что Python - это динамический язык, хотя cmd_add является ссылкой на функцию в вашем источнике, ничто не мешает ему ссылаться на другой объект в разное время.

Python создаст привязку, когда интерпретатор пройдет строку, где определена функция, и будет ссылаться на эту функцию до тех пор, пока вы не удалите ссылку или не свяжете ее с чем-то другим

0 голосов
/ 19 марта 2012

В скрипте Python выражения оцениваются сверху вниз, поэтому вы не можете ссылаться на функцию до ее определения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...