2015-07-21 75 views
0

我在做一个需要能够处理大量命令的SocketServer。所以为了防止我的RequestHandler过长,它会根据命令调用不同的函数。我的困境是如何让信息发回给客户。滥用产量

目前,我正在使功能“屈服”它想要发送回客户端的所有内容。但我认为这可能不是pythonic的方式。

# 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

您也可以使用lambda。应该使测试更容易。 – 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-premature)) – goncalopp

+0

对不起,我的例子很糟糕,但是有时需要花费很多时间才能获得数据。我喜欢返回元组的想法,将研究这一点。 – Lufftre