You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中while循环调用类方法无法重复获取用户输入的问题

问题

调用game.play()时,首次循环运行正常:玩家猜中正确数字会显示提示并结束游戏;但猜错数字时,while循环会陷入无限循环,持续打印"Your guess is too high! Guess again!"或"Your guess is too low! Guess again!"。原本期望while循环每次迭代时,都能调用self.num.number_guess()获取用户输入的新猜测值。

原代码

from dataclasses import dataclass, field
import random

@dataclass
class NumberGuess:
    range: list[int] = field(default_factory=list)
    target: int = 0
    range_beginning: int = None
    range_end: int = None
    user_guess: int = None

    def set_range(self):
        while self.range_beginning is None or self.range_end is None:
            try:
                self.range_beginning = int(input('Enter the first number in the range: '))
                self.range_end = int(input('Enter the last number in the range: '))                
            except ValueError:
                print('Please enter numbers only.')
                self.range_beginning = None
                self.range_end = None

        self.range.append(self.range_beginning)
        self.range.append(self.range_end)

    def randomize(self):
        if self.range_end > self.range_beginning:
            self.target = random.randint(self.range_beginning,self.range_end)
        else:
            self.target = random.randint(self.range_end,self.range_beginning)

    def number_guess(self):
        while self.user_guess is None:
            try:
                self.user_guess = int(input(f'Guess a number between {self.range_beginning} and {self.range_end}: '))
            except ValueError:
                print('Please enter numbers only.')

@dataclass
class Game:
    winner: bool = False
    num: NumberGuess() = NumberGuess()  # 语法错误

    def is_correct(self):
        if self.num.target == self.num.user_guess:
            print(f'You guessed the correct number: {self.num.target}!')
            self.winner = True
        else:
            if self.num.user_guess > self.num.target:
                print('Your guess is too high! Guess again!')
            else:
                print('Your guess is too low! Guess again!')
            self.winner = False

    def play(self):
        self.num.set_range()
        self.num.randomize()
        while self.winner is False:
            self.num.number_guess()
            self.is_correct()

def main() -> None:
    game = Game()
    game.play()

问题原因

  1. user_guess未重置:NumberGuess类的user_guess属性在第一次用户输入后就不再是None,导致number_guess()方法里的while self.user_guess is None循环直接跳过,无法获取新的用户输入。
  2. Game类字段初始化错误:num: NumberGuess() = NumberGuess()是无效语法,dataclass中初始化类类型字段需使用field(default_factory=NumberGuess),否则会引发意外问题。

修复方案

方案一:修改number_guess()方法,每次调用强制获取新输入

移除while self.user_guess is None的判断逻辑,改为每次调用都重新获取用户输入:

def number_guess(self):
    while True:
        try:
            self.user_guess = int(input(f'Guess a number between {self.range_beginning} and {self.range_end}: '))
            break
        except ValueError:
            print('Please enter numbers only.')

方案二:猜错后重置user_guess为None

在Game类的is_correct()方法的else分支中,添加重置user_guess的逻辑:

def is_correct(self):
    if self.num.target == self.num.user_guess:
        print(f'You guessed the correct number: {self.num.target}!')
        self.winner = True
    else:
        if self.num.user_guess > self.num.target:
            print('Your guess is too high! Guess again!')
        else:
            print('Your guess is too low! Guess again!')
        self.winner = False
        self.num.user_guess = None  # 重置为None,让下一次number_guess能重新获取输入

额外修复:修正Game类字段初始化语法

将num: NumberGuess() = NumberGuess()改为:

num: NumberGuess = field(default_factory=NumberGuess)

完整修复后的代码

from dataclasses import dataclass, field
import random

@dataclass
class NumberGuess:
    range: list[int] = field(default_factory=list)
    target: int = 0
    range_beginning: int = None
    range_end: int = None
    user_guess: int = None

    def set_range(self):
        while self.range_beginning is None or self.range_end is None:
            try:
                self.range_beginning = int(input('Enter the first number in the range: '))
                self.range_end = int(input('Enter the last number in the range: '))                
            except ValueError:
                print('Please enter numbers only.')
                self.range_beginning = None
                self.range_end = None

        self.range.append(self.range_beginning)
        self.range.append(self.range_end)

    def randomize(self):
        if self.range_end > self.range_beginning:
            self.target = random.randint(self.range_beginning,self.range_end)
        else:
            self.target = random.randint(self.range_end,self.range_beginning)

    def number_guess(self):
        while True:
            try:
                self.user_guess = int(input(f'Guess a number between {self.range_beginning} and {self.range_end}: '))
                break
            except ValueError:
                print('Please enter numbers only.')

@dataclass
class Game:
    winner: bool = False
    num: NumberGuess = field(default_factory=NumberGuess)

    def is_correct(self):
        if self.num.target == self.num.user_guess:
            print(f'You guessed the correct number: {self.num.target}!')
            self.winner = True
        else:
            if self.num.user_guess > self.num.target:
                print('Your guess is too high! Guess again!')
            else:
                print('Your guess is too low! Guess again!')
            self.winner = False

    def play(self):
        self.num.set_range()
        self.num.randomize()
        while self.winner is False:
            self.num.number_guess()
            self.is_correct()

def main() -> None:
    game = Game()
    game.play()

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 05:55:42