Python:程序不会在其他目录

时间:2015-05-08 01:56:05

标签: python directory

我正在运行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循环,我假设它不会运行,除非它从自己的文件夹/目录中调用?

4 个答案:

答案 0 :(得分:1)

您的问题从第5行开始:

arr = glob.glob('./*.txt')

您正在告诉glob在本地目录中查找所有.txt文件。由于您是一个目录,因此您没有这些文件。

您收到的是ValueError,因为该行变量为空。

编写时,您需要从该目录运行它。

编辑: 我看到它的方式你有三个不同的选择。

  1. 您只需使用完整路径运行脚本(假设它是可执行的)

    〜/文档/ BudgetAutomation / BillList / bill.py

  2. 您可以将完整路径放入文件中(尽管不是非常Pythonic)

    arr = glob.glob('/ home / [username] / Documents / BudgetAutomation / BillList / * .txt')

  3. 您可以使用sys.argv传递文件中的路径。这将是我个人的首选方式。使用os.path.join来输入正确的斜杠。

    arr = glob.glob(os.path.join(sys.argv 1,'* .txt'))

答案 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

的文件列表