Обратные вызовы и события в python

Я делаю бота, чтобы связать IRC и DC (прямое соединение) вместе. Существует реализация на C++, за которой я следил, но в ней нет всех функций, которые нам нужны.

Я использую библиотеку IRC для Python, которая действительно хорошо закодирована. Я могу зарегистрировать некоторые обработчики обратного вызова для различных событий IRC (в частности, для получения публичного сообщения). Эта функция обратного вызова может ссылаться на объекты, созданные в основном выполнении Python, из потока в библиотеке IRC.

Вот мои обратные вызовы:

def on_connect(connection, event):
    connection.join(ircSettings['channel'])

def on_disconnect(connection, event):
    sys.exit()

def on_pubmsg(connection, event):
    hubClient.sendMessage(event.source.split('!')[0] + ': ' + event.arguments[0])

И вот как я их настроил:

# Create the IRC client
ircClient = irc.client.IRC()
try:
    ircConnection = ircClient.server().connect(ircSettings['server'], ircSettin$
except irc.client.ServerConnectionError, x:
    print x
    sys.exit()

# Set the IRC event handlers
ircConnection.add_global_handler("welcome", on_connect)
ircConnection.add_global_handler("pubmsg", on_pubmsg)
ircConnection.add_global_handler("disconnect", on_disconnect)

Мне очень нравится это решение, так как оно делает код очень аккуратным (особенно в этом примере). Однако я понятия не имею, как изменить мою библиотеку DC для генерации этих событий.

Основной интерес представляет способность обратного вызова ссылаться на hubClient, который создается в основной программе Python следующим образом:

# Create the DC client
hubClient = DC.DirectConnect(dcSettings)
hubClient.connect(dcSettings['hub'])

Первоначально я передал указатель функции в свою библиотеку DC, чтобы она запускалась всякий раз, когда получено сообщение:

def messageHandler(nick, msg):
    if nick is not ircSettings['nick']:
        ircConnection.privmsg(ircSettings['channel'], nick + ': ' + msg)

dcSettings = {
    'nick': 'dans_bot',
    'sharesize': 10*1024**3, # 10GB
    'ip': '0.0.0.0', # XXX: This might not matter, but needed for library
    'hub': ('192.168.1.129', 411),
    'handler': messageHandler
}

Но я получаю сообщение об ошибке:

NameError: global name 'ircConnection' is not defined

Как я могу настроить свой клиент DC для создания обратного вызова таким образом, чтобы я все еще мог ссылаться на эти локальные (по отношению к основному исполнению) объекты?

Изменить: я добавил объявление для «ircConnection».


person dantheman    schedule 24.06.2013    source источник


Ответы (2)


Я полагаю, что ircConnection — это сторонний модуль. И простой импорт этого модуля может решить эту ошибку global nameircConnectionis not defined. Попробуйте import ircConnection в своем основном модуле

person Nakamura    schedule 24.06.2013

Единственная проблема в вашем коде заключается в том, что ссылка на ircConnection сначала видна внутри блока try-except, и если это не удается, то var будет None. Просто напишите ircConnection = None перед попыткой.

# Create the IRC client
ircClient = irc.client.IRC()
ircConnection = None 
try:
    ircConnection = ircClient.server().connect(ircSettings['server'], ircSettin$
except irc.client.ServerConnectionError, x:
    print x
    sys.exit()

# Set the IRC event handlers
ircConnection.add_global_handler("welcome", on_connect)
ircConnection.add_global_handler("pubmsg", on_pubmsg)
ircConnection.add_global_handler("disconnect", on_disconnect)
person David Hernandez    schedule 03.07.2016