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无条件后的Areturn无法达到;我猜你有这些用于调试,但保留它们是没有意义的。(我假设print lifromdir也不是真的需要。)

  • 您的函数名称应该更好地表明该函数的实际作用。open_file是一个无用的名称,因为该函数实际上对文件的内容做了一些事情。

  • 同样,变量名应该表明变量内容的含义。如果你不能想出一个好名字,这表明该变量是不必要的。另一个迹象是您存储了一次值,然后使用它一次;在这里涉及变量的唯一原因是分解表达式并给某些东西命名,但是在这里你有简单的表达式并且没有好名字。所以只写一个表达式。

  • 您可能希望将目录列表写为行列表,因此请使用换行符而不是逗号将它们连接起来。

  • 有比读取整个文件并拆分结果字符串更简单的方法来获取文件中的行列表。它们通常也会更有效率。实际上,您不需要先构造列表,然后再从列表中构建集合;您可以直接创建集合。

  • open_fileopen_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 回答