Linux上的Python:如果列表未知,则使用If Elif Elif Elif遍历列表

时间:2020-07-20 03:24:18

标签: python linux usb shutil libusb

我正在尝试制作一个python脚本,该脚本自动将文件从我的内部驱动器移动到插入的任何USB驱动器。但是,此目标路径是不可预测的,因为我并非每次都使用相同的USB驱动器。使用Raspbian Buster完整版时,到目前为止,我能做的最好的事情就是将其自动挂载到/ media / pi / xxxxx中,其中xxxxxx部分是不可预测的。我正在尝试为此添加脚本帐户。我可以通过以下方式获得驱动器安装点

drives = os.listdir("/media/pi/")

但是我担心有些会因为在被拉出之前没有被卸载而无效(我需要在没有显示器,键盘,VNC或任何用户输入的情况下运行此设备,而不是替换USB驱动器)。因此,我认为我可能需要在if elif elif elif链中进行一系列try catch语句,以确保目标确实是有效的,但是我不知道该如何执行而无需进行硬编码名称中的名称。我知道如何通过一组我不知道的名称进行迭代的唯一方法是

for candidate_drive in drives:

但是我不知道如何使它进入下一个候选驱动器,除非当前驱动器抛出异常。

系统:Raspberry Pi 4,Raspbian buster完整,Python 3.7。

旁注:我也在具有usbmount的Buster lite上进行了尝试,它确实具有可预知的挂载名称,但是我无法安装exfat和ntfs,这是另一篇文章的问题。

更新:我在考虑这件事,也许我需要尝试一下,但else语句中的除外是pas而else是break?我正在尝试。

Update2:我重新考虑了我的问题,也许不是寻找异常以确定何时尝试下一个可能的驱动器,否则我可以寻找成功的传输并中断循环。

import os
import shutil

files_to_send = os.listdir("/home/outgoing_files/")
source_path = "/home/outgoing_files/" 
possible_USB_drives = os.listdir("/media/")

for a_possible_drive in possible_USB_drives:
    try:
        destpath = os.path.join("/media/", a_possible_drive)           
        for a_file in files_to_send:
            shutil.copy(source_path + a_file, destpath)
    except:
        pass # transfer to possible drive didn't work
    else:
        break # Stops this entire program bc the transfer worked!

1 个答案:

答案 0 :(得分:1)

如果目录的侧面有无数个目录,等等。。。不能使用嵌套的for cicle。您需要实现一个递归调用函数。如果您在目录中有目录,那么您想查看所有目录,可以使用相同的函数遍历目录列表,反复遍历目录,直到找到文件为止。

让我们看一个例子,您具有这样的路径结构:

path
    dir0
        dir2
            file3
    dir1
        file2
    file0
    file1

您现在无法确定要迭代此结构中的al个元素需要多少for个cicle。您可以在单个目录的所有元素上调用迭代(for cicle),并对元素内部的元素执行相同的操作。在此结构dirN中,N是数字表示目录,而fileN是文件。

您可以使用os.listdir()函数来获取目录的内容:

print(os.listdir("path/")) 

返回:

['dir0', 'dir1', 'file0.txt', 'file1.txt']

使用此功能和所有目录,您可以获取结构的所有元素。您只需要遍历所有目录。具体来说是目录,因为如果使用文件:

print(os.listdir("path/file0.txt"))

您收到一个错误:

NotADirectoryError: [WinError 267]

但是,请记住,在Python中存在生成器表达式。

字符串工作

如果您有mainpath,则需要访问其中包含完整字符串引用的目录:"path/dirN"。您无法直接访问不在.py脚本范围内的文件:

print(os.listdir("dir0/"))

遇到错误

FileNotFoundError: [WinError 3]

因此,您需要始终使用实际路径设置初始主路径的格式,通过这种方式您可以访问结构的所有元素

过滤

我说过,您可以使用生成器表达式来递归获取结构的目录。让我们看一下功能:

def searchfile(paths: list,search: str):
    for path in paths:
        print("Actual path: {}".format(path))

        contents = os.listdir(path)
        print("Contents: {}".format(contents))
   
        dirs = ["{}{}/".format(path,x) for x in contents if os.path.isdir("{}/{}/".format(path,x)) == True]
        print("Directories: {} \n".format(dirs))

        searchfile(dirs,search)

在此函数中,我们使用os.listdir()获取实际路径的内容,然后使用生成器表达式对其进行过滤。显然,我们将递归函数调用与实际路径的目录结合使用:searchfile(dirs,search)

该算法可以应用于任何文件结构,因为path参数是一个列表。因此,您可以迭代包含目录的目录,以及其中包含更多目录的目录。

如果要获取特定文件,可以使用第二个参数search。您还可以实现条件并获取找到的文件的特定路径:

if search in contents:
    print("File found! \n")
    print("{}".format(os.path.abspath(search)))
    sys.exit()

希望对您有所帮助。