原始问题
我已经创建了一个等待特定字符串出现在串行端口上的函数,并返回所有字符读取,直到找到该字符串,否则返回false。这很方便,但我想知道它是否被认为是不好的做法?
澄清:
主要目标是等待特定字符串在给定的时间内出现。除IO错误外,可能的结果为True(字符串确实出现)或False 次要目标是获取整个输出,因为在寻找实际答案之前可能存在我想要解析的信息。我想可能是我可以在一个返回值中合并主要和次要目标。
def MyFunc(s, timeout) :
test = get_some_input(timeout)
if test.endswith(s)
return test
else
return False
编辑:另一个建议的答案是提出异常。我不认为这是一个好主意,因为超时是预期的行为。我的意思是,如果有一个用于指定超时的参数,那么超时是可能的结果,而不是例外。
编辑2: 由于我需要存储输入,因此使用类是正确的解决方案。 wait for函数有一个明确的返回值,但是在超时之前读取的整个字符串也是可访问的。
class Parser :
def __init__(self, sport_name):
self.currentMsg = ''
self.ser = serial.Serial(sport_name, 115200)
def WaitFor(self, s, timeOut=None):
self.ser.timeout = timeOut
self.currentMsg = ''
while self.currentMsg.endswith(s) != True :
# should add a try catch here
c=self.ser.read()
if c != '' :
self.currentMsg += c
else :
print 'timeout waiting for ' + s
return False
return True
答案 0 :(得分:26)
返回None
代替False
吗?
答案 1 :(得分:10)
我相信正统的Python设计将返回None。 manual说:
无
此类型具有单个值。有 具有此值的单个对象。这个 通过对象访问对象 内置名称无。它习惯了 表示许多人没有价值 情况,例如,从中返回 没有显式返回的函数 任何东西。它的真值是错误的。
答案 2 :(得分:7)
最好返回一个字符串AND一个布尔值(如标题中所示),而不是返回一个字符串或一个布尔值。您不必弄清楚返回值的含义。它应该是完全明确的,正交问题应该分成不同的变量。
(okay,value) = get_some_input(blah);
if (okay): print value
我倾向于不再返回元组,因为它感觉很有趣。但这样做完全有效。
返回“无”是一个有效的解决方案,已在此处提及。
答案 3 :(得分:5)
方便的是在这种情况下返回一个空字符串。
除了Python中的空字符串,无论如何都会评估为False。所以你可以这样称呼:
if Myfunc(s, timeout):
print "success"
另外:正如S.Lott指出的那样,真正的Pythonic方式是返回None。虽然我选择在字符串相关的函数中返回字符串。确实是一个偏好的问题。
此外,我假设Myfunc的调用者只关心获取一个字符串来操作 - 空或不。如果调用者需要检查超时问题等,最好使用异常或返回None。
答案 4 :(得分:5)
如果字符串及时到达,您可以返回该字符串,或者提出指示超时的适当异常。
答案 5 :(得分:3)
也许如果你返回一个像(False,None)和(True,test)这样的元组,它会更好,因为你可以分开评估它们而不会增加不必要的复杂性。
编辑:也许串口上出现的字符串是“”(可能是预期的),所以返回True可以说它是以这种方式到达的。答案 6 :(得分:2)
要添加Ber的观点,您可能需要考虑其他因素。如果你使用一个空字符串或无,你可以打开门,看看“哑”的错误。另一方面,如果引发异常,则强制执行正在运行的任何操作以中止。
例如,请考虑以下代码:
result = MyFunc(s, timeout)
if result[0] == 'a':
do_something()
如果操作超时并且获得空字符串或None,则会引发异常。因此,您必须将其更改为:
result = MyFunc(s, timeout)
if result and result[0] == 'a':
do_something()
这些类型的更改往往会增加并使您的代码更难理解。
当然,我确信你对此的回答将是“我不会那样做”或“那不会发生”的答案,我的回答是“即使你不这样做”通过这个功能进入它,如果你习惯这样做,你最终会成功。“这些类型的错误几乎总是你通常不会想到的极端情况的结果。
答案 7 :(得分:1)
这是Python生成器的经典用例。 yield
关键字提供了一种迭代离散集的简单方法,而无需立即返回整个事物:
def MyFunc(s, timeout) :
test = get_some_input(timeout)
while test.endswith(s)
yield test
test = get_some_input(timeout)
for input in MyFunc(s, timeout):
print input
这里的关键是没有返回值来指定输入的结束;相反,你只需到达迭代器的末尾。有关生成器here的更多信息。