如何在Python中使用变量名打开一个或多个文件?
我是一个Python新手,第一次在这里发帖...
我正在制作一个大规模磁盘复制程序,之前遇到的问题都解决得不错。现在我想根据用户选择的复选框,打开1到n(最多28个)个文件(实际上是在Linux中的驱动器,比如/dev/sdc、/dev/sdd等)。
我用的代码大概是这样的,但在执行到eval那一行时,出现了“不能给函数调用赋值”的错误。这不是我实际的代码,只是模拟了我的问题,请忽略文件路径。
有什么合适的方法可以做到这一点呢?
#!/usr/bin/env python
class snippet:
def __init__(self):
# open files for binary writing
file_in = open('/dev/null', 'rb')
ints = [0, 1, 2, 3]
for i in ints:
num = str(i)
eval('f_out' + num) = open('/tmp/tmp' + num, 'wb')
# READ/WRITE CODE GOES HERE
# close files
file_in.close()
for i in ints:
num = str(i)
print "Number: " + num
eval("f_out" + num).close()
if __name__ == '__main__':
app = snippet()
谢谢,
罗伊
3 个回答
1
与其使用 eval()
来创建一堆有名字的文件对象(每次想对其中一个操作时都得再用 eval()
),不如把它们都存储在一个或多个列表里,甚至可以把输入文件也放进去,然后根据需要进行处理。这样做有几个好处:首先,你可以很方便地对这些文件对象进行统一操作,还可以轻松改变它们的数量。例如:
class Snippet:
NUM_OUTPUT_FILES = 4
FILE_NAMES = (['/dev/null'] +
['/tmp/tmp%d' % n for n in xrange(NUM_OUTPUT_FILES)])
def __init__(self):
# open all the files
self.files = ([open(self.FILE_NAMES[0], 'rb')] +
map(lambda fname: open(fname, 'wb'), self.FILE_NAMES[1:]))
def run(self):
# READ/WRITE CODE GOES HERE
# for example
# data = self.files[0].read(1024)
# self.files[1].write(data)
# data = self.files[0].read(1024)
# self.files[3].write(data)
# close all files opened
map(file.close, self.files)
if __name__ == '__main__':
app = Snippet()
app.run()
2
你可以用一个包含file
对象的列表来实现这个功能。一般来说,使用eval
被认为是不太好的做法。无论如何,在你的程序中使用eval
都是不正确的。不过,你可以用exec
来做同样的事情,但这也不推荐。
exec("f_out%d = open('%s%d', 'wb')" % (num, "/tmp/tmp", num))
你应该使用类似这样的东西:
open_files = []
num = 4
for i in range(num):
open_files.append(open("/tmp/tmp" + i, 'wb'))
6
不要使用eval;应该保持一个字典(编辑:或者列表)来存储文件句柄,而不是使用单独命名的变量。
#!/usr/bin/env python
def main():
outfiles = [open("/tmp/tmp{0}".format(i), 'wb') for i in (0,1,2,3)]
with open('/dev/null', 'rb') as inf:
# do reading/writing
pass
for i,f in enumerate(outfiles):
print("Closing number {0}".format(i))
f.close()
if __name__ == '__main__':
main()