2015-07-21 4 views
0

Я создаю SocketServer, который должен иметь возможность обрабатывать множество команд. Поэтому, чтобы мой RequestHandler не становился слишком длинным, он будет вызывать разные функции, зависящие от команды. Моя дилемма заключается в том, как заставить его отправлять информацию обратно клиенту.Неправильное использование

В настоящее время я делаю функции «урожай» всего, что он хочет отправить обратно клиенту. Но я думаю, что это, вероятно, не пифонический путь.

# RequestHandler 
func = __commands__.get(command, unkown_command) 
for message in func(): 
    self.send(message) 


# example_func 
def example(): 
    yield 'ip: {}'.format(ip) 
    yield 'count: {}'.format(count) 

    . . . 

    for ping in pinger(ip,count): 
     yield ping 

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

func(self) 

, а затем в функции

def example(handler): 
    . . . 
    handler.send('ip: {}'.format(ip)) 

Но этот способ не чувствовать себя намного лучше.

+0

Вы также можете использовать лямбда. Необходимо облегчить тестирование. – Sorin

+0

@Sorin Вы имеете в виду что-то вроде: func (lambda x: self.send (x))? – Lufftre

+0

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

ответ

1
def example(): 
    yield 'ip: {}'.format(ip) 
    yield 'count: {}'.format(count) 

Что меня поражает, как странно, в этом решении не использование самого yield (который может быть вполне допустимо), но тот факт, что вы теряете много информации, превращая ваши данные в строки преждевременно.

В частности, для такого рода данных, просто возвращающего словарь и обработкой отправки в вызывающем кажется более удобным для чтения:

def example(): 
    return {'ip': ip, 'count': count} 

Это также поможет вам отделить содержание и представление, что может быть полезно, если вы хотите, например, вернуть данные, закодированные в XML, но позже переключиться на JSON.

Если вы хотите получить промежуточные данные, другая возможность использует кортежи: yield ('ip', ip). Таким образом, вы сохраняете исходные данные и можете начать обработку значений непосредственно вне функции.

+0

Я не хочу, чтобы клиент ожидал ответа. Как только информация будет восстановлена, клиент должен ее получить. – Lufftre

+0

@ Lufftre Вы можете использовать кортежи тогда: 'yield ('ip', ip)'. Но обратите внимание, что это усложняет работу, и если получение ip занимает много времени или данные действительно большие, это, вероятно, значительно ухудшит производительность и не будет иметь заметного преимущества (см. [Преждевременная оптимизация] (http://stackoverflow.com/questions/385506/when-is-optimization-beforeature)) – goncalopp

+0

Извините, мой пример довольно плох, но да, иногда для получения данных требуется много времени. Мне нравится идея вернуть кортежи, посмотрим на это. – Lufftre

Смежные вопросы