-2

これがコードです-非常に単純です-しかし、それはプログラムの主要部分の最初の例外を無限に与えます-最初の入力で-最初の入力で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
4

2 に答える 2

1

まず第一に、私はあなたのコードについて非常に多くの批判的なフィードバックをするつもりです. 覚えておいてほしいのは、私がこれを行っているのは、コーディングの悪さを悪用するためではなく、純粋に教育目的で行っていることであり、あなたが行ったことのより良い方法を示すことだけです。

以下にリストすることを行うと問題は解決しますが、ブロック全体が削除されるだけtryです。したがって、これはあなたの質問に対する直接的な回答ではありません。私がこれに時間を費やしていても、実際に回答の承認を求めているわけではありません。私は初心者を助けようとしているだけです。

これらのすべてが間違いというわけではありません。あなたがしていることを行うための最良の方法ではありません。初心者にとって、あなたのコードは実際にはそれほど悪くはありませんが、常に新しいことを学ぶ必要があります。コードに関連するいくつかのことを次に示します。

1.「クラスメイン」

最初の問題、class main()あなたは:最後から行方不明ですが、これはクラスではなく関数であることを意味していると思いますか? def main():関数を定義するには、 に変更します。クラスはオブジェクトを作成するためのものであり、関数は単純なタスクを完了するためのものです。

2. 例外

ユーザーから入力を取得し、それが有効な入力かどうかを確認する方法は 10 億通りあります。残念ながら、あなたの方法はそれらの 1 つではありません。for ループを実行する 1 つの方法を次に示します。

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 = 1また、やなどの変数を使用するのwhile i == 1:は悪いコーディングです。代わりにwhile True:を呼び出してループを停止するbreakか、上記のように実行してください。

前述したように、これらはこれを実装するためのいくつかの方法にすぎません。うまくいけば、あなたに合った方法が見つかると思いますが、できる限りシンプルにしてください。

3.changeAttribute

あなたのchangeAttribute()方法は私には役に立たないようです。呼び出す代わりに、無駄なメソッドを使用せずに、まったく同じ結果を得るpeopleList[-1].changeAttribute(name, None, None)ことができます。peopleList[-1].name = name

4.人リスト[-1]

を使用peopleList[-1]してオブジェクトを取得するのも良い方法ではありません。代わりに、メイン関数の最初の行で新しい人を定義する必要がありますperson = details()(詳細の名前も Person に変更しますが、呼び出し) person.name = name。名前を取得している詳細に置き換えます。すべての for ループが完了したら、 を呼び出しますpeopleList.append(person)。コードの最初の行から person 定義を残して、ユーザーの名前、住所、番号を一時ローカル変数に取得し、最後の行で call を使用することもできますpeopleList.append(details(name, address, number))が、最初の方法が推奨されます。

5.キャメルケースクラス名

class details:コメントで既に述べたように、クラスには ( doの代わりに) CamelCaseNaming を使用する必要がありますclass Details:。これは決してエラーではなく、間違いでもありませんが、他のプログラマーもコードを理解できるように、CamelCasing を使用することをお勧めします。これはプログラマーの間の単なる習慣であり、クラスに名前を付けるためにグローバルに使用されている方法です。

于 2012-11-26T19:32:12.307 に答える
0

Mahi は、プログラムを改善する方法をうまく説明してくれました。彼のアドバイスに従い、より単純で読みやすいコードを書くように努めれば、手に負えないバグが少なくなることがわかると思います。

しかし、私はあなたの特定の質問に答えたかった:

名前のない例外を明示的に発生させたときだけでなくexcept (Exception)、対応するブロック内に例外があるたびにブロックが実行されます。tryこれを回避するには、特定の例外を発生させてキャッチする必要があります。

無限ループを再現できる唯一の方法は、入力を求めないIdeone.com オンライン インタープリターを使用することでした (事前に入力する必要があります)。これにより EOFError 例外が発生し、これが によってキャッチされexcept、無限ループにつながりました。同様のことをしたと思います(または、例外を発生させるようなことをしました)。

于 2012-11-26T19:58:28.390 に答える