if、elif、else链不正确?

2 投票
3 回答
1935 浏览
提问于 2025-04-17 02:32

我正在学习《Learn Python the Hard Way》这本书,但遇到了一些困难。书里给了一个单元测试,让你写一个函数来满足这些测试。但是当我把这个函数导入到交互式命令行中测试时,无论输入什么,都会返回'direction',我搞不清楚为什么。

这是我的代码:

def pos(item):
    """ Get part of speech for item. """
    pos = ''
    if item == 'north' or 'south' or 'east':
        return 'direction'
    elif item == 'go' or 'kill' or 'eat':
        return 'verb'
    elif item == 'the' or 'in' or 'of':
        return 'stop'
    elif item == 'bear' or 'princess':
        return 'noun'
    else:
        try:
            int(item)
            return 'number'
        except ValueError:
            return 'error'

3 个回答

1
if item == 'north' or 'south' or 'east':

这个部分用来判断在“或”运算符之间的内容是否为真。非空字符串的真值是“真”,所以如果输入是 'west',那么它的结果就是:

if False or True or True:

不过,你想要的是

if item == 'north' or item == 'south' or item == 'east':

,或者说,更符合Python风格的是:

if item in ('north', 'south', 'east'):
4

你用的 or 不太对。应该是这样:

if item == 'north' or item == 'south' or item == 'east':

或者,更常见的写法是:

if item in ('north', 'south', 'east')

之所以出现错误,是因为 Python 在处理这个表达式时加了括号。你可能以为它在做:

if item == ('north' or 'south' or 'east')

但实际上发生的是:

if (item == 'north') or ('south') or ('east')

'south' 是一个非空字符串,所以它总是被认为是 True。 (不过,前面的写法也不行,因为 'north' or 'south' or 'east' 会被计算成 'east',这是因为 Python 在处理 or 时的短路特性。但这个比较复杂,你可以先不考虑。)


顺便说一下,你可能会更喜欢下面这种写法,虽然你用的也没问题。

items = {}
items['north'] = items['south'] = items['east'] = 'direction'
items['go'] = items['kill'] = items['eat'] = 'verb'
items['the'] = items['in'] = items['of'] = 'stop'
items['bear'] = items['princess'] = 'noun'

try:
    return items[item]
except KeyError:
    pass

try:
    int(item)
except ValueError:
    pass
else:
    return 'number'

return 'error'
8

你应该这样写:

if item == 'north' or item == 'south' or item == 'east':

或者,你也可以这样写:

if item in ('north', 'south', 'east'):

其他的分支也是一样的道理。

为了说明你原来的代码为什么不行,我们来看看Python是怎么解析下面这个表达式的:

item == 'north' or 'south' or 'east'

Python的处理方式如下(注意括号表示解析的顺序):

(item == 'north') or 'south' or 'east'

这里有三个子表达式。item == 'north' 这个判断可能是假的(除非你输入的正好是 'north')。但是,'south' 或者 'east' 在布尔上下文中(也就是在条件判断里)总是会被认为是 True,所以你最终得到的是 (item == 'north') or True or True,这当然是 True

撰写回答