简体   繁体   English

python分配变量混乱

[英]python assigning variable mess

I'm trying to write a script that 1. lists the content of a directory, creates a list of it(temp.txt), turns the list into a string and writes it into a file 2. opens an other text file(t.txt) and compares the content of the opened file with the previously saved file (temp.txt) and returns the difference. 我正在尝试编写一个脚本,该脚本包括:1.列出目录的内容,创建目录的列表(temp.txt),将该列表转换为字符串并将其写入文件2.打开另一个文本文件(t (.txt),并将打开的文件的内容与先前保存的文件(temp.txt)进行比较,然后返回差异。 The idea is that the script would be able to tell if there are new files in a folder. 这个想法是该脚本将能够告诉您文件夹中是否有新文件。 The function dif works great as a standalone script but when nested as a function I get this error message: 函数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

and the script: 和脚本:

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)

Use global li inside your functions. 在函数内部使用global li From what I understand, the Python interpreter will look for globals at the global scope only if it cannot find them locally. 据我了解,Python解释器仅在无法在本地找到全局变量的情况下才会在全局范围内寻找全局变量。 It is enough that they are set somewhere in the local method (even if it's after a possible "read") for the interpreter to bind them to local scope, thus ignoring any global declaration and resulting in the error that you see. 将它们设置在local方法中的某个位置(即使在可能的“读取”之后)就足够了,以便解释器将它们绑定到本地范围,从而忽略任何全局声明并导致您看到的错误。

For instance: 例如:

a = 3

def b():
    print a
    a = 1

Will fail, even though a is defined globally at the time the print statement is executed. 即使在执行print语句时全局定义a也会失败。 Adding global a at the beginning of the function body would make it work. 在函数体的开头添加global a会使它起作用。

There are numerous conceptual problems here. 这里有很多概念上的问题。 For the sake of actually teaching something, I've gone over the code completely: 为了实际教学,我已经彻底检查了代码:

  • A print after an unconditional return can't be reached; 无条件return后无法print I guess you had these in for debugging, but there's no point keeping them around. 我想您已经将它们用于调试,但是没有必要保留它们。 (I'm assuming print li from dir is not really needed either.) (我假设也确实不需要从dir print li 。)

  • Your function names should do a better job of indicating what the function actually does. 您的函数名称应能更好地表明函数的实际作用。 open_file is a useless name, since the function actually does something with the file's contents. open_file是一个无用的名称,因为该函数实际上会对文件的内容执行某些操作。

  • Variable names, similarly, ought to indicate the meaning of the variable's contents. 类似地,变量名称应指出变量内容的含义。 If you can't come up with a good name, it's a sign that the variable is unnecessary. 如果您不能拿出好名字,则表明该变量是不必要的。 Another sign is that you store the value once and then use it once; 另一个迹象是,您将值存储一次,然后使用一次。 the only reason to involve a variable here is to break up an expression and give something a name, but here you have simple expressions and no good names. 此处涉及变量的唯一原因是分解一个表达式并给它起一个名字,但是这里您有简单的表达式而没有好名字。 So just write out a single expression. 因此,只写一个表达式。

  • You presumably want to write the directory list as a list of lines, so join them with newlines, not commas. 您可能想将目录列表写为行列表,因此请使用换行符(而不是逗号)将它们连接起来。

  • There are even simpler ways to get a list of the lines in a file, than reading the entire file and splitting up the resulting string. 与读取整个文件并拆分结果字符串相比,还有什至更简单的方法来获取文件中的行列表。 They'll generally be more efficient, too. 它们通常也会更高效。 In fact, you don't need to construct the list and then build a set from the list; 实际上,您不需要构造列表,然后从列表中构造一个集合。 you can create the set directly. 您可以直接创建集合。

  • open_file and open_another perform the same task, and thus are redundant. open_fileopen_another执行相同的任务,因此是多余的。 Just pass in a filename and use it. 只需传入一个文件名并使用它即可。

  • Try to separate responsibilities of functions into logical blocks. 尝试将功能职责划分为逻辑块。 In particular, don't handle I/O in the same place that you do the calculations. 特别是,请勿在进行计算的地方处理I / O。

  • In modern Python, we use with blocks to handle automatically closing the file when we're done with it. 在现代Python中,我们使用with块来处理完文件后自动关闭文件。

  • os.listdir already creates a list, so there is no reason to make a loop to append the list items to another list. os.listdir已经创建了一个列表,因此没有理由进行循环以将列表项附加到另一个列表。 You could, for example, append the whole thing at once with + ; 例如,您可以使用+一次附加整个内容; but your apparent intent is to append to an empty list, so you could just assign directly. 但您的明显意图是将其追加到一个空列表,因此您可以直接分配。 In fact, there is no need for the global variable or the assignment, so we'll just use the os.listdir result directly. 实际上,不需要全局变量或赋值,因此我们将直接使用os.listdir结果。

Your program can be this simple: 您的程序可以很简单:

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')

(And that assumes that creating the directory file is actually a requirement...) (并且假定创建目录文件实际上是必需的...)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM