在Python中使用exec()函数和格式化字符串?

1 投票
2 回答
3554 浏览
提问于 2025-05-10 20:53

我有一个文件,里面是我的学校课程表,我想把文件中的每一行都变成一个列表。这个文件大概是这样的:

first:second:third:fourth:fifth
first:second:third:fourth:fifth

代码是这样的:

schedule_file = "school-schedule.txt"
with open(schedule_file) as schedule:
    for c, line in enumerate(schedule):
        exec("ln%s = schedule.read().split(':')" % str(c+1))

print(ln1)
print(ln2)
print(ln3)
print(ln4)
print(ln5)
print(ln6)
print(ln7)
print(ln8)
print(ln9)
print(ln10)

我知道这个文件有十行,所以为了测试,我想让它打印出这十个列表。不幸的是,它似乎只把第一行放进了叫做 ln1 的列表里,而从 ln2 开始,其他的列表都出现了一个叫做 NameError 的错误:

['first', 'second', 'third', 'fourth', 'fifth']
Traceback (most recent call last):
  File "D:\schedule.py", line 10, in <module>
    print(ln2)
NameError: name 'ln2' is not defined

难道在 exec() 函数里不能使用格式化字符串,还是我犯了什么其他的低级错误?

相关文章:

  • 暂无相关问题
暂无标签

2 个回答

1

你在第一次循环后就已经读取了整个文件,所以你永远无法继续到第一个 exec("ln%s = .....:

exec("ln%s = schedule.read().split(':')" % str(c+1))
                      ^^^
                     .read() # reads whole/rest of file

你可以直接使用 readlines 方法,然后通过索引来访问内容:

with open(schedule_file) as schedule:
    data = schedule.readlines()
ln1 = data[0].split(":")
.....

或者可以结合 map 方法来进行分割:

data = list(map(lambda x: x.split(":"),schedule))

你也可以使用字典,但其实这样做并没有比直接用列表和索引访问更有优势。

如果你真的想要十个变量,那就进行解包:

 with open(schedule_file) as schedule:
    ln1,ln2 ....ln10 = map(lambda x: x.split(":"),schedule
2
for c, line in enumerate(schedule):
    exec("ln%s = schedule.read().split(':')" % str(c+1))

你从文件中读取的内容在变量 line 里,但你却写成了:

exec("ln%s = schedule.read().split(':')....

而不是:

exec("ln%s = line.split(':')...

无论如何,每当你发现自己在写这样的变量名:

print(ln1)
print(ln2)
print(ln3)
print(ln4)

这些变量名之间只差一个数字时,你就需要停下来,换用列表来处理。如果你有一个叫 ln 的列表,那么列表里的项目已经有了名字 ln[0], ln[1] 等等。所以,你可以这样做:

with open('data.txt') as f:
      ln = [line.rstrip().split(':') for line in f]

print(ln)
print(ln[0])
print(ln[1])

--output:--
$ cat data.txt
a:b:c:d
e:f:g:h

$ python prog.py
[['a', 'b', 'c', 'd'], ['e', 'f', 'g', 'h']]
['a', 'b', 'c', 'd']
['e', 'f', 'g', 'h']

撰写回答