Python 全局和局部变量:代码如何工作?

Python global and local variable: How does the code work?

我遇到了一个允许用户输入水果名称的代码。根据输入,从购物篮列表中搜索,如果在列表中,则显示数量。

如果没有找到水果,用户可以输入该水果的数量并将其添加到列表中。

basket = [
    {'fruit': 'apple', 'qty': 20},
    {'fruit': 'banana', 'qty': 30},
    {'fruit': 'orange', 'qty': 10}
]

fruit = input('Enter a fruit:')

index = 0
found_it = False

while index < len(basket):
    item = basket[index]
    # check the fruit name
    if item['fruit'] == fruit:
        found_it = True
        print(f"Basket has {item['qty']} {item['fruit']}(s)")
        break

    index += 1

if not found_it:
    qty = int(input(f'Enter the qty for {fruit}:'))
    basket.append({'fruit': fruit, 'qty': qty})
    print(basket)

但是我不明白外部if条件的逻辑。它指的是哪个found_it?是在 while 语句之前定义的(全局的)还是其中定义的(局部的)?外部 if 是如何工作的?

在 python 中,您没有显式声明变量。它可能令人困惑,但一旦变量存在于范围内,在这种情况下是全局的,那么分配给它会改变它的值而不是创建一个新值。最好的时刻是当你拼错某些东西时,python 会认为你用该值声明了新变量,而原始变量不会改变。我真的不明白为什么 python 的创建者引入了这样的歧义,幸运的是新语言正在避免这个错误。

这并不是一个真正的答案,而是向您展示了如何完全回避使用可变值来决定下一步该做什么的问题。


请注意 Python 有一个 while-else 结构,使 found_it 变量变得不必要。

basket = [
    {'fruit': 'apple', 'qty': 20},
    {'fruit': 'banana', 'qty': 30},
    {'fruit': 'orange', 'qty': 10}
]

fruit = input('Enter a fruit:')

index = 0

while index < len(basket):
    item = basket[index]
    # check the fruit name
    if item['fruit'] == fruit:
        print(f"Basket has {item['qty']} {item['fruit']}(s)")
        break

    index += 1
else:
    qty = int(input(f'Enter the qty for {fruit}:'))
    basket.append({'fruit': fruit, 'qty': qty})
    print(basket)

循环的 else 子句仅在未使用 break 退出循环时执行,即当您更改 found_it 的值时。


有些不相关,您可以直接遍历 basket 的元素,而无需使用索引。

basket = [
    {'fruit': 'apple', 'qty': 20},
    {'fruit': 'banana', 'qty': 30},
    {'fruit': 'orange', 'qty': 10}
]

fruit = input('Enter a fruit:')

for item in basket:
    # check the fruit name
    if item['fruit'] == fruit:
        print(f"Basket has {item['qty']} {item['fruit']}(s)")
        break
else:
    qty = int(input(f'Enter the qty for {fruit}:'))
    basket.append({'fruit': fruit, 'qty': qty})
    print(basket)

elsefor 的行为方式与 while 的行为方式相同:它仅在循环“自然”退出时执行,在这种情况下是通过耗尽迭代器而不是当循环条件变为假。

运行 带有调试器的代码显示,一旦遇到第一个 found_it,它就会在全局和本地创建,因此内部循环中的 found_it 会更改值您最初声明的。

关于外循环的工作,if not是一个检查真假的条件,即只有当值为假时才会执行。

使用常规 if-else 会更容易。