1

1. ディレクトリの内容をリストし、そのリスト (temp.txt) を作成し、リストを文字列に変換してファイルに書き込むスクリプトを作成しようとしています 2. 他のテキスト ファイル (t .txt) を開き、開いたファイルの内容を以前に保存したファイル (temp.txt) と比較し、その差を返します。アイデアは、フォルダーに新しいファイルがあるかどうかをスクリプトが判断できるようにすることです。関数 dif はスタンドアロン スクリプトとしてはうまく機能しますが、関数としてネストすると、次のエラー メッセージが表示されます。

Enter directory >  /users
Traceback (most recent call last):
  File "/Users/alkopop79/NetBeansProjects/comparefiles.py", line 33, in <module>
    dir()
  File "/Users/alkopop79/NetBeansProjects/comparefiles.py", line 12, in dir
    li.append(fname)
UnboundLocalError: local variable 'li' referenced before assignment

そしてスクリプト:

import os

li = []
lu = []
le = []

def dir():
    dir = raw_input("Enter directory >  ")
    path=dir  # insert the path to the directory of interest
    dirList=os.listdir(path)
    for fname in dirList:
            li.append(fname)
    li = ','.join(str(n) for n in li)   
    targetfile = open("temp.txt", 'w')
    targetfile.write(li)
    targetfile.close() 
    print li

def open_file():
    txt = open('t.txt')
    li = txt.read()
    la = li.split()
    return la
    print len(li)

def open_another():
    txt = open('temp.txt')
    lu = txt.read()
    lo = lu.split()
    return lo
    print len(li)

dir()
a = open_file()
b = open_another()
print set(a) & set(b)
4

2 に答える 2

1

関数内で使用global liします。私が理解していることから、Python インタープリターは、ローカルで見つからない場合にのみ、グローバル スコープでグローバルを探します。インタープリターがそれらをローカルスコープにバインドするには、ローカルメソッドのどこかに(「読み取り」の可能性がある場合でも)それらを設定するだけで十分です。したがって、グローバル宣言は無視され、表示されるエラーが発生します。

例えば:

a = 3

def b():
    print a
    a = 1

ステートメントの実行a時にグローバルに定義されていても、失敗します。関数本体の先頭にprint追加すると機能します。global a

于 2012-05-14T10:10:15.647 に答える
0

ここには多くの概念上の問題があります。実際に何かを教えるために、コードを完全に調べました。

  • print無条件にreturn到達できない後。デバッグ用にこれらを持っていたと思いますが、それらを保持しておく意味はありません。(print lifromdirも実際には必要ないと思います。)

  • 関数名は、関数が実際に何をするかを示すのにより良い仕事をするべきです。open_file関数は実際にファイルの内容で何かを行うため、役に立たない名前です。

  • 同様に、変数名は、変数の内容の意味を示す必要があります。適切な名前が思いつかない場合は、その変数が不要であることを示しています。もう 1 つの兆候は、値を 1 回保存してから 1 回使用することです。ここで変数を使用する唯一の理由は、式を分割して何かに名前を付けることですが、ここでは式が単純で適切な名前がありません。したがって、単一の式を書き出すだけです。

  • おそらくディレクトリリストを行のリストとして書きたいので、カンマではなく改行で結合してください。

  • ファイル全体を読み取って結果の文字列を分割するよりも、ファイル内の行のリストを取得する簡単な方法があります。それらは一般的により効率的でもあります。実際、リストを作成してからリストからセットを作成する必要はありません。セットを直接作成できます。

  • open_file同じタスクをopen_another実行するため、冗長です。ファイル名を渡して使用するだけです。

  • 機能の責任を論理ブロックに分離するようにしてください。特に、計算を行うのと同じ場所で I/O を処理しないでください。

  • 最新の Python では、withブロックを使用して、処理が完了したときにファイルを自動的に閉じる処理を行います。

  • os.listdirはすでにリストを作成しているため、ループを作成してリスト項目を別のリストに追加する理由はありません。+たとえば、 ;を使用して一度にすべてを追加できます。しかし、あなたの明らかな意図は空のリストに追加することであるため、直接割り当てることができます。実際、グローバル変数や代入は必要ないので、os.listdir結果をそのまま使用します。

あなたのプログラムは次のようにシンプルです:

import os

def make_dirfile(directory):
    with open('temp.txt', 'w') as dirfile:
        dirfile.write('\n'.join(os.listdir(directory)))

def unique_lines_of(filename):
    with open(filename) as input_file:
        return set(input_file)

make_dirfile(raw_input("Enter directory >  "))
print unique_lines_of('temp.txt') & unique_lines_of('t.txt')

(そして、ディレクトリファイルの作成が実際には要件であると仮定しています...)

于 2012-05-14T11:04:31.897 に答える