是否避免将变量声明为None那么糟糕?

时间:2014-11-05 01:41:27

标签: python nonetype try-except

我正在研究Python中的一个经典学生问题,找到一系列条目中的最大值和最小值。通常,我希望通过将所有有效的用户条目放在列表中来实现这一点,但我们应该逐个评估每个条目,因为它来自用户。 (在本课程中,我们将在列表之前覆盖循环。)

由于我没有使用列表,我不愿意将变量声明为None,然后评估“最大值是无或最大< new”,因为前一种情况只会发生一次。相反,我用min()和max()来解决这个问题,直到我找到了下面的解决方案,这在我看来是优雅的,但是我的同伴已经被解雇为憎恶。

所以这就是问题:这是try / except的有效用法吗?它是否比评论的替代品更少pythonic? (当然,最狡猾的方式是min([list])但是我在这里。)

#smallest = None

while True:
    num = raw_input("Enter a number: ")
    if num == "done" : break
    try:
        num = int(num)
    except:
        print 'Invalid input'
        continue

    try:
        smallest = min(num,smallest)
    except NameError:
        smallest = num

#    if num < smallest or smallest is None:
#        smallest = num    

print "Minimum is", smallest

2 个答案:

答案 0 :(得分:2)

不,这是一个非常荒谬的使用try / except。

预先声明它并将其定义为None,然后将其更新为

smallest = num if smallest is None else min(num, smallest)

或者,您可以将其初始化为smallest = [],然后将其更新为

smallest = [min(smallest + [num])]

然后用

结束
print("Minimum is {}".format(smallest) if smallest else "No numbers!")

答案 1 :(得分:2)

虽然尝试和处理异常通常是Python的一个基本原则 - EAFP, or Easier to Ask Forgiveness than Permission - 但它总是是合适的。

至少,NameError是一种事情,通常更多的是你的代码中的逻辑错误需要修复而不是要处理的特殊情况,所以&#39 ;非常糟糕&#34;代码味道&#34;这里。

另外,考虑如果用户从不输入任何数字会发生什么。如果您已初始化smallest = None,则会打印Minimum is None,这不是太不合理。如果您未将其初始化,则会从未处理的NameError打印出堆栈跟踪,这对用户友好程度要低得多。


但是有一个简单的选择:只需选择一个比任何有效输入都大的起始值,然后你就不需要检查(无论是通过EAFP还是LBYL):{{1永远都是正确的答案。

您可以使用什么价值?好吧,无穷大显然比任何整数都大,所以你可以从smallest = min(num, smallest)开始。

(我不确定float('inf')对于无价值情况是否优于Minimum is inf,但它肯定比追溯更好。)


与此同时,值得注意的是,有一个更清洁的设计,首先避免了这个问题。只需将您的代码分解出来以生成整数流,然后您可以使用生成的可迭代执行任何操作。例如:

Minimum is None

这具有构建列表的所有优点(您可以在其上调用def numbers(): while True: num = raw_input("Enter a number: ") if num == "done" : break try: yield int(num) except: print 'Invalid input' smallest = min(numbers()) )而没有缺点(您不必在内存中实际构建列表)。

你可以通过在min周围使用双参数iter来产生字符串生成器,然后将它分两步转换为整数生成器,然后将其传递给raw_input。但我认为新手更容易理解这种方式。