簡體   English   中英

Python:程序不會在其他目錄中運行

[英]Python: Program will not run in other 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

這里發生了什么? 我是否無法在終端中正確運行compile and run命令? 要知道的另一個注意事項是,我最終會從另一個文件調用此代碼,因此我不會運行for循環,因為除非從自己的文件夾/目錄中調用它,否則它不會運行?

您的問題從第5行開始:

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

您要告訴glob在本地目錄中查找所有.txt文件。 由於您位於一個目錄中,因此沒有這些文件。

因為行變量為空,所以出現ValueError。

在編寫時,您將需要從該目錄運行它。

編輯:我認為它有三個單獨的選項。

  1. 您可以簡單地使用完整路徑運行腳本(假設它是可執行文件)

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

  2. 您可以將完整路徑放入文件中(盡管不是很Pythonic)

    arr = glob.glob('/ home / [用戶名] / Documents / BudgetAutomation / BillList / *。txt')

  3. 您可以使用sys.argv在文件中傳遞路徑。 這將是我個人的首選方式。 使用os.path.join放置正確的斜杠。

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

正如eomer所解釋的那樣 ,問題在於'./*.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以后有人執行os.chdir

您無需創建該范圍對象即可遍歷全局結果。 您可以這樣做:

for file_path in arr:
    with open(file_path) as text_file:
        #...code below...

我猜為什么會出現該異常,是因為存在文本文件包含不符合您需求的內容。 您從該文件中讀取了一行,可能類似於“ foo | bar”,然后拆分結果為[“ foo”,“ bar”]。

如果要避免此異常,可以捕獲它:

try:
    bill_no, bill_name, trash = line.split('|', 2)
except ValueError:
    # You can do something more meaningful but just "pass"
    pass

您必須在此處使用絕對路徑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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM