这段代码是我最近在另一个问题中写的,我不确定它是最优的。不过,我找不到一个减少缩进的方法来做这件事。有?在
def msg_generator(self):
''' Provides messages until bot dies '''
while self.alive:
for msg in self.irc.recv(self.buffer).split(('\r\n').encode()):
if len(msg) > 3:
try:
yield Message(msg.decode())
except Exception as e:
self.log('%s %s\n' % (except_str, str(e)))
我听不下去了,但我听太多了。现在有四个凹痕。在
上面代码的问题并不是嵌套太深,而是代码的扩展性太强,不够有意。我的意思是,当你组装机器所需的齿轮、轮子和杠杆已经就位并(大概)起作用时,你能看到的有标签的模块太少了,有太多的问题被“完成”在太多隐含的、未标记的方式上,导致代码难以阅读(对于“完整”部分,你愿意听听吗http://www.infoq.com/presentations/Simple-Made-Easy-这是一个非常有启发性的谈话,它指出了代码的问题)。在
我举个例子:
我想你说的是“信息”。那么为什么不调用这个变量
message
?为什么是缩写。那个词?message
更清楚了。在现在是}在大多数情况下是可以的。这给了我们
^{pr2}$for message in xxx
。什么是xxx
?你已经知道了。在python英语中,确实,for apple in appples; for pear in pears
应该是一种好的、合理的语义书写方式:for ... in
循环从元素集合中一次一个地挑出元素,因此{这些信息来自哪里?根据您的代码,它们是执行
self.irc.recv(self.buffer).split(('\r\n').encode())
操作的结果。在这真是个大麻烦。{{10}绝对是irc.recv()来解码所有的缓冲区返回,而不是先拆分,然后逐行解码。在
但这是次要的问题。重要的是:无论需要什么低级代码来提供
irc
中的下一行列表,它可能不应该出现在这里。更确切地说,像或者也许
是合适的。当然,这些细节还有很多争议。就我个人而言,我尽量不把我的数据状态对象(主要是泛型类型)与我的库(库中的命名功能的无状态集合)合并在一起。上面链接的简单易用的演示文稿提出了完全相同的观点,顺便说一句,而且还设法令人信服地进行了辩论。(旁白:这当然与当前主流的OOP思想不谋而合,但是google搜索Yegge在名词王国中的执行,如果你相信
OOP ≡ good
n'importe quois)目前的方法都是关于回复消息,而不是接收消息。把它想象成报纸上的一个真正的专栏:这里我们在办公室里,负责思考并汇编答案,然后发给读者;那些打开收到的报纸邮件、拿起电话、筛选电子邮件的人,在另一个办公室里有着完全不同的工作。因此,如何打开信封应该是你应该在这个地方实现的。需要外包。在
是否要将
messages
变量显式化或将其合并为内联API调用,取决于可用空间等多个因素,以及是否希望在例程的另一个点循环使用该返回值。我觉得这很好:for ... in
将透明地与生成器和列表返回器一起工作,这很好。在总是用最一般的、但不松散的、最模块化的、但不是“原子化”的方式来思考代码。在
如果我要针对您的代码编写测试用例,我肯定会挑出
irc.recv
部分并单独测试。用这样的方式来思考你的代码:什么是好的模块,每个模块都有一个单独的关注点,一个合理的隔离级别,健全的调用参数,这些都有利于良好的可测试性?我的代码部分的合理名称是什么?-如果你坚持这样做,你的代码就不会再嵌套太深了。在上面代码的问题并不是嵌套太深,而是代码的扩展性太强,不够有意。我的意思是,当你组装机器所需的齿轮、轮子和杠杆已经就位并(大概)起作用时,你能看到的有标签的模块太少了,有太多的问题被“完成”在太多隐含的、未标记的方式上,导致代码难以阅读(对于“完整”部分,你愿意听听吗http://www.infoq.com/presentations/Simple-Made-Easy-这是一个非常有启发性的谈话,它指出了代码的问题)。在
我举个例子:
我想你说的是“信息”。那么为什么不调用这个变量
message
?为什么是缩写。那个词?message
更清楚了。在现在是}在大多数情况下是可以的。这给了我们
^{pr2}$for message in xxx
。什么是xxx
?你已经知道了。在python英语中,确实,for apple in appples; for pear in pears
应该是一种好的、合理的语义书写方式:for ... in
循环从元素集合中一次一个地挑出元素,因此{这些信息来自哪里?根据您的代码,它们是执行
self.irc.recv(self.buffer).split(('\r\n').encode())
操作的结果。在这真是个大麻烦。{{10}绝对是irc.recv()来解码所有的缓冲区返回,而不是先拆分,然后逐行解码。在
但这是次要的问题。重要的是:无论需要什么低级代码来提供
irc
中的下一行列表,它可能不应该出现在这里。更确切地说,像或者也许
是合适的。当然,这些细节还有很多争议。就我个人而言,我尽量不把我的数据状态对象(主要是泛型类型)与我的库(库中的命名功能的无状态集合)合并在一起。上面链接的简单易用的演示文稿提出了完全相同的观点,顺便说一句,而且还设法令人信服地进行了辩论。(旁白:这当然与当前主流的OOP思想不谋而合,但是google搜索Yegge在名词王国中的执行,如果你相信
OOP ≡ good
n'importe quois)目前的方法都是关于回复消息,而不是接收消息。把它想象成报纸上的一个真正的专栏:这里我们在办公室里,负责思考并汇编答案,然后发给读者;那些打开收到的报纸邮件、拿起电话、筛选电子邮件的人,在另一个办公室里有着完全不同的工作。因此,如何打开信封应该是你应该在这个地方实现的。需要外包。在
是否要将
messages
变量显式化或将其合并为内联API调用,取决于可用空间等多个因素,以及是否希望在例程的另一个点循环使用该返回值。我觉得这很好:for ... in
将透明地与生成器和列表返回器一起工作,这很好。在总是用最一般的、但不松散的、最模块化的、但不是“原子化”的方式来思考代码。在
如果我要针对您的代码编写测试用例,我肯定会挑出
irc.recv
部分并单独测试。用这样的方式来思考你的代码:什么是好的模块,每个模块都有一个单独的关注点,一个合理的隔离级别,健全的调用参数,这些都有利于良好的可测试性?我的代码部分的合理名称是什么?-如果你坚持这样做,你的代码就不会再嵌套太深了。在从我的头顶上,你可以这样做:
或者你可以重构成函数。在
^{pr2}$或者用这样的方法:
最后一个选项并不完美,因为如果出现异常,那么函数将返回
None
,这不是一条真正的消息,因此您也可以在之后使用filter()
或使用另一个端点句柄None
msg的相关问题 更多 >
编程相关推荐