我正在运行ubuntu 12.04并通过终端运行程序。我有一个文件,当我在当前目录中时编译并运行没有任何问题。以下示例,
david@block-ubuntu:~/Documents/BudgetAutomation/BillList$ pwd
/home/david/Documents/BudgetAutomation/BillList
david@block-ubuntu:~/Documents/BudgetAutomation/BillList$ python3.4 bill.py
./otherlisted.txt
./monthlisted.txt
david@block-ubuntu:~/Documents/BudgetAutomation/BillList$
现在当我返回一个目录并尝试运行相同的代码时,我收到一条错误消息ValueError: need more than 1 value to unpack
。下面是当我运行示例代码一个文件夹,然后是下面的示例代码时发生的情况。
david@block-ubuntu:~/Documents/BudgetAutomation$ python3.4 /home/david/Documents/BudgetAutomation/BillList/bill.py
Traceback (most recent call last):
File "/home/david/Documents/BudgetAutomation/BillList/bill.py", line 22, in <module>
bill_no, bill_name, trash = line.split('|', 2)
ValueError: need more than 1 value to unpack
下面的代码bill.py
。该程序从它所在的文件夹中读取两个文本文件,并将这些行解析为变量。
#!/usr/bin/env python
import glob
# gather all txt files in directory
arr = glob.glob('./*.txt')
arrlen = int(len(arr))
# create array to store list of bill numbers and names
list_num = []
list_name = []
# for loop that parses lines into appropriate variables
for i in range(arrlen):
with open(arr[i]) as input:
w = 0 ## iterative variable for arrays
for line in input:
list_num.append(1) ## initialize arrays
list_name.append(1)
# split line into variables.. trash is rest of line that has no use
bill_no, bill_name, trash = line.split('|', 2)
# stores values in array
list_num[w] = bill_no
list_name[w] = bill_name
w += 1
这里发生了什么?我没有在终端中正确运行编译和运行命令吗?另一个需要注意的是,我最终从另一个文件中调用此代码并且它不会运行for循环,我假设它不会运行,除非它从自己的文件夹/目录中调用?
答案 0 :(得分:1)
您的问题从第5行开始:
arr = glob.glob('./*.txt')
您正在告诉glob在本地目录中查找所有.txt文件。由于您是一个目录,因此您没有这些文件。
您收到的是ValueError,因为该行变量为空。
编写时,您需要从该目录运行它。
编辑: 我看到它的方式你有三个不同的选择。
答案 1 :(得分:1)
作为eomer explains,问题是'./*.txt'
是相对于当前工作目录的相对路径。如果您没有从所有*.txt
个文件所在的目录中运行,则无法找到任何内容。
如果*.txt
文件应该与脚本位于同一目录中,请使用与脚本相同的目录,而不是当前工作目录。
这样做的标准方法是将这样的代码放在脚本的顶部:
import os
import sys
scriptdir = os.path.abspath(os.path.dirname(sys.argv[0]))
argv[0]
获取脚本本身的路径。因此,如果您将脚本作为python BillList/bill.py
运行,则会'BillList/bill.py'
。 *
dirname
只是获取文件的路径,并为您提供文件所在目录的路径。因此,在这种情况下,BillList
。
abspath
对路径进行规范化和绝对化。 ** 因此,您将获得/home/david/Documents/BudgetAutomation/BillList/
。这就是*.txt
文件所在的目录。
然后,而不是这个:
glob.glob('./*.txt')
...你这样做:
glob.glob(os.path.join(scriptdir, '*.txt'))
*实际上,在某些平台上,您将获得绝对路径,而不是相对路径,这意味着后面的abspath
是不必要的。但是为了便携性,它值得做。一个更大的问题是,在某些情况下,您将只获得bill.py
,没有路径。曾经有过这样的情况:值得检查并尝试__file__
,但据我所知,在任何现代平台上都不是这样 - 并且有些情况__file__
是错误的但是argv[0]
是对的。
**对于相对路径,它相对于当前工作目录绝对值。这就是为什么在脚本顶部执行此操作非常重要 - 以防有人稍后执行os.chdir
。
答案 2 :(得分:0)
您不需要创建该范围对象来迭代glob结果。你可以这样做:
for file_path in arr:
with open(file_path) as text_file:
#...code below...
为什么引发异常的原因,我想,是否存在包含不符合您需要的内容的文本文件。你从那个文件中读取了一行,这可能就像&#34; foo | bar&#34;,然后它的分裂结果是[&#34; foo&#34;,&#34; bar&#34; ]
如果你想避免这个例外,你可以抓住它:
try:
bill_no, bill_name, trash = line.split('|', 2)
except ValueError:
# You can do something more meaningful but just "pass"
pass
答案 3 :(得分:0)
您必须在此处使用绝对路径arr = glob.glob('./*.txt')
。
执行arr = glob.glob('/home/abc/stack_overflow/*.txt')
如果可能,请使用以下代码
dir_name = "your directory name" # /home/abc/stack_overflow
[file for file in os.listdir(dir_name) if file.endswith('txt')]
这将为您提供要glob