繁体   English   中英

为什么我在 python 中使用 raw_input 得到一个无限循环?

[英]Why do I get an infinite loop with raw_input in python?

这是代码 - 非常简单 - 但它无限地给了我程序主要部分的第一个异常 - 甚至没有要求用户输入我认为它应该在 - 在raw_input的第一个输入 - 我是初学者总体上很好地掌握了语言 - 有什么想法吗? 谢谢

import re,sys

#program to take details of people name, address and telephone number from user
#user must specify number of people first

class details:
    def __init__(self,name=None,address=None,tel=None):
        self.name=name
        self.address=address
        self.tel=tel

    def changeAttribute(self,name=None,address=None,tel=None):
        if name!=None:
            self.name=name
        if address!=None:
            self.address=address
        if tel!=None:
            self.tel=tel



class main(): 

    peopleList =[]
    a=1

    while a==1:    
        try:

            numOfPeople = raw_input("enter number of people:")
            if re.search('[^0-9\n]', numOfPeople):
                raise Exception
        except (Exception):
            print ("illegal input ,must only be numbers - Please try again")
        else:
            numOfPeople=str(numOfPeople)
            a=0

    for i in range(0,numOfPeople):
        x=1
        while x==1:
            try:    

                name=raw_input("Please enter name")
                if re.search('[^a-zA-Z\n]',name):
                    raise Exception
            except (Exception):
                print("illegal name - Please use only letters")
            else:
                peopleList.extend(details(name))
                x=0

        x=1    
        while x==1:
            try:    

                address=raw_input("Please enter address")
                if re.search('[^a-zA-Z\n]',address):
                    raise Exception
            except (Exception):
                print("illegal name - Please use only letters")
            else:
                peopleList[-1].changeAttribute(None,address,None)
                x=0

        x=1    
        while x==1:
            try:    

                tel=raw_input("Please enter telephone number")
                if re.search('[^0-9]',tel):
                    raise Exception
            except (Exception):
                print("illegal name - Please use only numbers")
            else:
                peopleList[-1].changeAttribute(None,address,None)
                x=0

首先,我将针对您的代码提供大量批评性反馈。 请记住,我这样做不是为了滥用您的不良编码,我这样做纯粹是出于教学目的,只是想向您展示做您所做的事情的更好方法。

执行我将在下面列出的操作将解决您的问题,但只会导致它删除整个try块。 所以这不是你问题的直接答案,即使我花时间在这上面,我实际上也没有要求接受答案。 我只是(无聊)试图帮助初学者。

并非所有这些甚至都是错误,它们只是不是做你正在做的事情的最好方法。 对于初学者来说,您的代码实际上并没有那么糟糕,但是总是有新的东西需要学习,这里有一些与您的代码相关的东西:

1.“班主”

第一个问题,你缺少的class main() :从最后开始,我想这应该是一个函数,而不是一个类? 将其更改为def main():来定义一个函数。 类用于创建对象,函数用于完成简单的任务。

2. 例外

有十亿种方法可以从用户那里获取输入并检查它是否是有效输入。 不幸的是,你的方式不是其中之一。 这是执行 for 循环的一种方法:

for i in range(numOfPeople):

    # Get user's name
    name = raw_input("Please enter name: ")

    # While name has incorrect characters
    while re.search('[^a-zA-Z\n]',name):

        # Print out an error
        print("illegal name - Please use only letters")

        # Ask for the name again (if it's incorrect, while loop starts again)
        name = raw_input("Please enter name: ")

    # .extend is used for appending lists to other lists
    # details is a class, not a list, so use .append instead
    peopleList.append(details(name))

您也可以使用中断,或者我更喜欢的方式是创建一个返回值的函数......如果没有很好的理由,不要使用异常,大多数时候它们只是在你的路上. 此外,使用诸如i = 1while i == 1:这样的变量是糟糕的编码,而是使用while True:并通过调用break停止循环,或者像我上面那样做。

正如我所提到的,这些只是实现这一点的几种方法,希望您能找到适合您的方法,但请尽可能保持简单。

3.更改属性

你的changeAttribute()方法对我来说似乎没用。 而不是调用peopleList[-1].changeAttribute(name, None, None)你可以只做peopleList[-1].name = name来获得完全相同的结果,而不是使用无用的方法。

4.人名单[-1]

使用peopleList[-1]来获取你的对象也不是一个好方法,相反你应该在你的主函数person = details()的第一行定义一个新人(我也会将 details 重命名为 Person,但你的电话) 并在每个 for 循环中,只需说person.name = name并用您获得的任何详细信息替换 name。 现在在所有 for 循环完成后,调用peopleList.append(person) 您也可以从代码的第一行中删除人员定义,将用户的姓名、地址和号码放入临时局部变量中,然后在最后一行调用peopleList.append(details(name, address, number)) ,尽管第一种方法值得推荐。

5. CamelCaseClassNames

正如我在评论中已经提到的,您应该为您的类使用 CamelCaseNaming(而不是class details: do class Details: :)。 这不是任何可能的错误,甚至不是错误,但最好使用 CamelCasing,以便其他程序员也能理解您的代码。 这只是程序员之间的一种习惯,全球使用的命名类的方式。

Mahi 在您改进程序的方法方面做得很好,我认为如果您遵循他的建议并努力编写更简单、更易读的代码,您会发现难以处理的错误更少。

但我想回答你的具体问题:

每次在相应的try块中出现异常时,您的except (Exception)块都会执行,而不仅仅是在您显式引发未命名异常时。 为避免这种情况,您应该引发并捕获特定异常。

我可以重现无限循环的唯一方法是使用Ideone.com 在线解释器,它不提示输入(您必须提前输入输入)。 这引发了一个 EOFError 异常,该异常被您的except捕获,并导致无限循环。 我怀疑您做了类似的事情(或以其他方式做了一些引发异常的事情)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM