Python:可以同时返回布尔值和字符串吗?

Python:可以同时返回布尔值和字符串吗?,python,Python,原始问题 我已经做了一个函数,它正在等待一个特定的字符串出现在串行端口上,并返回所有读取的字符,直到找到该字符串为止,否则返回false。这很方便,但我想知道这是否被认为是不好的做法 澄清: 主要目标是等待特定的字符串在给定的时间内出现。除IO错误外,可能的结果为True(字符串确实出现)或False 第二个目标是获得整个输出,因为在寻找实际答案之前,可能有一些信息我想解析。我想我可以将主要目标和次要目标结合在一个返回值中 def MyFunc(s, timeout) : test =

原始问题

我已经做了一个函数,它正在等待一个特定的字符串出现在串行端口上,并返回所有读取的字符,直到找到该字符串为止,否则返回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

返回
None
而不是
False
是否更合适?

在这种情况下,方便的做法是返回一个空字符串

此外,Python中的空字符串无论如何都将计算为False。所以你可以这样称呼它:

if Myfunc(s, timeout):
    print "success"
另外:正如S.洛特所指出的,真正的蟒蛇方式是不返回任何东西。尽管我选择在字符串相关函数中返回字符串。这确实是一个偏好的问题


另外,我假设Myfunc的调用方只关心获取一个字符串来操作-空或不空。如果调用方需要检查超时问题等。。最好使用异常或不返回异常。

如果您返回一个元组(False,None)和(True,test),可能会更好,因为您可以单独评估它们,而不会增加不必要的复杂性


编辑:可能串行端口上出现的字符串是“”(可能是预期的),因此返回True可以表示它是以这种方式到达的。

如果字符串及时到达,则可以返回该字符串,或者引发一个适当的异常,指示超时。

我相信传统的Python设计是不返回任何字符串。报告说:

没有

此类型只有一个值。有 具有此值的单个对象。这 对象是通过 内置名称无。习惯于 表示在许多情况下没有一个值 情况,例如,从 不显式返回的函数 任何东西它的真值是假的


最好返回字符串和布尔值(如标题中所示),而不是返回字符串或布尔值。您不必弄清楚返回值的含义。它应该是完全明确的,并且应该将正交问题分成不同的变量

(okay,value) = get_some_input(blah);
if (okay): print value
我倾向于不经常返回元组,因为它感觉很有趣。但这样做是完全正确的


返回“None”是一个有效的解决方案,这里已经提到过。

要补充Ber的观点,您可能需要考虑其他一些因素。如果使用空字符串或不使用空字符串,则为“哑”类型的bug敞开了大门。另一方面,如果引发异常,则会强制中止正在运行的任何操作的执行

例如,考虑下面的代码:

result = MyFunc(s, timeout)
if result[0] == 'a':
    do_something()
如果操作超时并获得空字符串或无字符串,这将引发异常。因此,您必须将其更改为:

result = MyFunc(s, timeout)
if result and result[0] == 'a':
    do_something()
这些类型的更改往往会使代码更难理解


当然,我相信你对这个问题的回答将是“我不会那样做”或“那不会发生”,我的回答是“即使你没有遇到这个函数,如果你养成了这样做的习惯,你最终也会这样做。”这些类型的bug几乎都是您通常不会想到的角落案例的结果。

这是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

这里的关键是没有返回值来指定输入的结束;相反,您只需到达迭代器的末尾。关于生成器的更多信息。

我更愿意采用@jelovirt的方法:无测试是明确的,不会增加复杂性。我一直喜欢python元组返回多个值+1.我喜欢这个想法,在同一个值字段中返回一个控制标志对我来说不太合适。在这种情况下,您有可能在将来更改有效值(如您所说,允许null)并使控制标志无效。即使在Python中引发异常比其他语言便宜,我不认为使用它们提供功能是一个好主意。+1:异常在这种情况下更有意义——你有一个“异常”条件——超时。事实上,我在一个使用串行端口等通信的项目中非常成功地使用了这种模式。超时异常处理重试,重新发送条件相当好。这种设计的问题在于它不能区分一种情况下的超时,以及s和test等于“”。-1:一点也不太像Pythonic。空字符串仍然是字符串。没有比这更好的了。一个例外更好。@utku karatas:不是偏好的问题,而是意义的问题。长度为零的字符串表示在分隔符或文件结尾之前读取零。“无”表示您没有阅读。@S.Lott:我假设Myfunc的调用方只关心获取一个字符串来处理-空或不空。@utku-karatas:string是一回事--timeout不是字符串。这仍然是一个意义问题,但正如其他ans中所描述的那样