2

Pythonを学びたいので、電話帳ディレクトリである最初のプログラムを書き始めました。名前と電話番号を追加したり、番号を削除したり、それらを検索したりするオプションがあります。取り外し部品で約2日間動かなくなってしまい、正しく動作しません。私はPythonIRCとすべてに参加しましたが、それを理解することができませんでした。基本的に、私のプログラムは番号をファイルのリストに保存します。ファイル内の特定の行を削除する方法がわかりませんが、ファイルの残りの部分はそのままにしておきます。誰かがこれを手伝ってくれませんか?

一部の人々は、一時ファイルを作成し、その行を削除してから、残りの行を元のファイルから一時ファイルにコピーすると、より簡単になるとアドバイスしています。次に、元のファイルを一時ファイルで上書きします。だから私はこれを試してきました...

if ui == 'remove':  
    coname = raw_input('What company do you want to remove? ') # company name
    f = open('codilist.txt', 'r') # original phone number listing        
    f1 = open('codilist.tmp', 'a') # open a tmp file

    for line in f:  
        if line.strip() != coname.strip():    
            for line in f: 
                f1.write(line)                             
            break         # WILL LATER OVERWRITE THE codilist.txt WITH THE TMP FILE
        else:
            f1.write(line)
    else:
        print 'Error: That company is not listed.'    
    f1.close()
    f.close()
    continue
4

6 に答える 6

4

あなたのファイルには、各行に < name >< whitespace >< number > のようなものが含まれていると思いますか? その場合は、if ステートメントに次のようなものを使用できます (エラー処理は含まれていません!)。

name, num = line.strip().split()
if name != coname.strip():
    # write to file



提案:

カスタム形式を使用する特定の理由がない限り、ファイル形式 json はこの種のタスクに非常に適しています。また、これらの例で 'with' ステートメントを使用していることにも注意してください。これにより、明示的にファイルを閉じる必要がなくなります。

情報を書き込むには:

import json

# Somehow build a dict of {coname: num,...}
info = {'companyA': '0123456789', 'companyB': '0987654321'}

with open('codilist.txt', 'w') as f:
    json.dump(info, f, indent=4) # Using indent for prettier files

ファイルを読み取り/修正するには:

import json

with open('codilist.txt', 'r+') as f:

    info = json.load(f)

    # Remove coname
    if coname in info:
        info.pop(coname)
    else:
        print 'No record exists for ' + coname

    # Add 'companyC'
    info['companyC'] = '0112233445'

    # Write back to file
    json.dump(info, f, indent=4)

これらの例では、python2.6 以降が必要です。2.5 を使用している場合は、次のインポートが必要になります。

import simplejson as json
from __future__ import with_statement

それが役立つことを願っています!

于 2012-06-22T13:12:48.383 に答える
1

これはかなり広範囲に書き直されたバージョンです:

  • 電話データはすべて Phonebook クラスにラップされます。データはメモリに保持されます(呼び出しごとに保存および再ロードされるのではなく)

  • csv モジュールを使用してデータをロードおよび保存します

  • 個々のアクションは短い関数またはメソッドに変換されます (コードの 1 つの大きなブロックではなく)

  • コマンドは関数ディスパッチ ディクショナリに抽象化されます (if/then テストのカスケードではなく)

これにより、理解と保守がはるかに簡単になります。

import csv

def show_help():
    print('\n'.join([
        "Commands:",
        "    help                   shows this screen",
        "    load [file]            loads the phonebook (file name is optional)",
        "    save [file]            saves the phonebook (file name is optional)",
        "    add {name} {number}    adds an entry to the phonebook",
        "    remove {name}          removes an entry from the phonebook",
        "    search {name}          displays matching entries",
        "    list                   show all entries",
        "    quit                   exits the program"
    ]))

def getparam(val, prompt):
    if val is None:
        return raw_input(prompt).strip()
    else:
        return val

class Phonebook(object):
    def __init__(self, fname):
        self.fname = fname
        self.data = []
        self.load()

    def load(self, fname=None):
        if fname is None:
            fname = self.fname
        try:
            with open(fname, 'rb') as inf:
                self.data = list(csv.reader(inf))
                print("Phonebook loaded")
        except IOError:
            print("Couldn't open '{}'".format(fname))

    def save(self, fname=None):
        if fname is None:
            fname = self.fname
        with open(fname, 'wb') as outf:
            csv.writer(outf).writerows(self.data)
            print("Phonebook saved")

    def add(self, name=None, number=None):
        name   = getparam(name,   'Company name? ')
        number = getparam(number, 'Company number? ')
        self.data.append([name,number])
        print("Company added")

    def remove(self, name=None):
        name = getparam(name, 'Company name? ')
        before = len(self.data)
        self.data = [d for d in self.data if d[0] != name]
        after = len(self.data)
        print("Deleted {} entries".format(before-after))

    def search(self, name=None):
        name = getparam(name, 'Company name? ')
        found = 0
        for c,n in self.data:
            if c.startswith(name):
                found += 1
                print("{:<20} {:<15}".format(c,n))
        print("Found {} entries".format(found))

    def list(self):
        for c,n in self.data:
            print("{:<20} {:<15}".format(c,n))
        print("Listed {} entries".format(len(self.data)))

def main():
    pb = Phonebook('phonebook.csv')
    commands = {
        'help':   show_help,
        'load':   pb.load,
        'save':   pb.save,
        'add':    pb.add,
        'remove': pb.remove,
        'search': pb.search,
        'list':   pb.list
    }
    goodbyes = set(['quit','bye','exit'])

    while True:
        # get user input
        inp = raw_input("#> ").split()

        # if something was typed in
        if inp:
            # first word entered is the command; anything after that is a parameter
            cmd,args = inp[0],inp[1:]

            if cmd in goodbyes:
                # exit the program (can't be delegated to a function)
                print 'Goodbye.' 
                break
            elif cmd in commands:
                # "I know how to do this..."
                try:
                    # call the appropriate function, and pass any parameters
                    commands[cmd](*args)
                except TypeError:
                    print("Wrong number of arguments (type 'help' for commands)")
            else:
                print("I didn't understand that (type 'help' for commands)")

if __name__=="__main__":
    main()
于 2012-06-22T14:02:03.603 に答える
0

このような単純なものは、 のすべてを読み取りf、一致しないすべての行を書き出します。

for line in f:
    if line.strip() != coname.strip():
        f1.write(line)
于 2012-06-22T01:08:03.097 に答える
0

ネッドの答えはうまくいくようです。これをまだ試していない場合は、Python の対話型デバッガーを問題の行の上に設定できます。line.strip()次に、との値を出力して、coname.strip()リンゴとリンゴを比較していることを確認できます。

for line in f:
    import pdb
    pdb.set_trace()
    if line.strip() != coname.strip():
        f1.write(line)

pdb コマンドのリストは次のとおりです

于 2012-06-22T02:22:21.157 に答える
0

私はこれを機能させました...

if ui == 'remove':  
    coname = raw_input('What company do you want to remove? ') # company name
    f = open('codilist.txt')
    tmpfile = open('codilist.tmp', 'w')
    for line in f:
        if coname in line:
            print coname + ' has been removed.'
        else:
           tmpfile.write(line)
    f.close()
    tmpfile.close()
    os.rename('codilist.tmp', 'codilist.txt')
    continue
于 2012-06-24T03:41:45.223 に答える
0

おそらく一時ファイルを追加 ('a') モードで開きたくないでしょう:

f1 = open('codilist.tmp', 'a') # open a tmp file

また、

for line in f:
    ...
    f1.write(line)

改行なしですべてをファイルに書き込みます。

必要な基本構造は次のとおりです。

for line in myfile:
    if not <line-matches-company>:
        tmpfile.write(line + '\n')   # or print >>tmpfile, line

実装する必要があります<line-matches-company>(質問には、それがどうあるべきかを知るのに十分な情報がありません-おそらく、データファイルから数行を表示した場合..?)

于 2012-06-22T08:21:43.753 に答える