You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python中函数内定义变量出现NameError的问题咨询(含代码)

问题分析与解决方案

嘿,我来帮你拆解一下这个报错的核心原因,以及怎么彻底解决它~

一、为什么会报"Name not defined"?

你的初始代码里犯了变量作用域的典型错误:

  • SECRET_WORD是在category()函数内部定义的局部变量,函数外部的prepare_secret_word()根本无权访问它——就像你把东西锁在自己房间里,别人进不来拿一样。
  • 你修改后的代码也有坑:
    1. category()里写了两个return,第一个return SECRET_WORD会直接终止函数,后面的return LENGTH_WORD永远不会执行,等于白写。
    2. prepare_secret_word()里两次调用category(),这会让用户被要求两次输入分类,而且两次返回的是不同的随机单词,逻辑完全乱了。

二、正确的解决思路

我们需要让category()一次性返回我们需要的两个值(秘密单词和它的长度),然后把这两个值传递给prepare_secret_word()使用,彻底绕过作用域的问题。

三、修正后的完整代码

import random

category_lists = {
    "objects": ["tables", "ladders", "chairs"],
    "animals": ["chicken", "dog", "cat"],
    "sports": ["basketball", "soccer", "rugby"]
}

def category():
    print("Please enter category name: ")
    response = ''
    # 循环提示用户输入合法分类
    while response.lower() not in category_lists:
        allowed_categories = ', '.join(category_lists.keys())
        response = input(f' One among the following [{allowed_categories}] : \n')
    # 获取选中分类的单词列表
    word_list = category_lists.get(response.lower())
    # 随机挑选秘密单词
    secret_word = random.choice(word_list)
    # 用元组打包返回秘密单词和它的长度
    return secret_word, len(secret_word)

GUESS_WORD = []
ALPHABET = "abcdefghijklmnopqrstuvwxyz"
letter_storage = []

def prepare_secret_word(secret_word, length_word) -> None:
    """Prepare secret word and inform user of it"""
    # 生成对应长度的占位符(这里用更简洁的方式替代循环append)
    GUESS_WORD.extend(["-"] * length_word)
    print(f"Ok, so the word You need to guess has {length_word} characters")
    print("Be aware that You can enter only 1 letter from a-z\n\n")
    # 打印待猜单词的占位符(原代码里的print_word_to_guess我补了个简单实现)
    print(' '.join(GUESS_WORD))

# 只调用一次category(),拿到秘密单词和长度
secret_word, length_word = category()
# 把两个值传递给prepare_secret_word使用
prepare_secret_word(secret_word, length_word)

四、关键修改点说明

  • 返回元组传递多值:让category()返回一个包含秘密单词和长度的元组,一次调用就能拿到所有需要的数据,避免重复调用函数导致的重复输入和随机值不一致问题。
  • 函数参数传递prepare_secret_word()通过参数接收需要的值,不再依赖全局变量或者跨函数访问局部变量,彻底解决作用域报错。
  • 简化代码:用category_lists.keys()直接获取分类名,用f-string格式化字符串,用["-"] * length_word快速生成占位符,让代码更简洁易读。

内容的提问来源于stack exchange,提问作者cena

火山引擎 最新活动