python指定变量混乱

时间:2012-05-14 10:05:51

标签: python syntax

我正在尝试编写一个脚本:1。列出目录的内容,创建它的列表(temp.txt),将列表转换为字符串并将其写入文件2.打开另一个文本file(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)

2 个答案:

答案 0 :(得分:1)

在您的功能中使用global li。据我所知,Python解释器只有在本地找不到全局范围时才会查找全局范围内的全局变量。只需将它们设置在本地方法中(即使它在可能的“读取”之后)就足以将解释器绑定到本地范围,从而忽略任何全局声明并导致您看到的错误。

例如:

a = 3

def b():
    print a
    a = 1

即使在a语句执行时全局定义print,也会失败。在函数体的开头添加global a将使其工作。

答案 1 :(得分:0)

这里存在许多概念问题。为了实际教授某些东西,我完全已经完成了代码:

  • 无法达到无条件print后的return;我猜你有这些用于调试,但没有必要保持它们。 (我假设print li中的dir也不是真的需要。)

  • 您的函数名称应该更好地指示函数实际执行的操作。 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')

(并且假设创建目录文件实际上是一个要求......)