扫描列表(文本,视为类似字节)并在项目不存在时追加 (Python)

Scan list (text, treating as bytes-like) and append if item not already present (Python)

如果路径不存在,我正在尝试将 jpg 文件路径附加到预先存在的文本列表中。我也在尝试将列表视为字节类以提高效率。

我能够使用以下代码根据搜索结果创建和附加列表:

#----> Variables

jpg_index = "/path/to/list_of_jpgs"

search_locations = ["path/to/folder/a", "path/to/folder/b"]

#---> Code 

#does my path exist
if os.path.exists(jpg_index):
    #for-loop to check all given search locations
    for search_location in search_locations:
        #find paths ending with jpg
        for path in Path(search_location).rglob('*.jpg'):
            #Open the index file / jpg list and append paths
            with open(jpg_index, 'a') as filehandle:
                filehandle.writelines('%s\n' % path)

但是,当我尝试检查预先存在的文本以查看是否应添加新路径时,似乎什么也没有发生。我正在尝试以下变体:

#----> Variables

jpg_index = "/path/to/list_of_jpgs"

search_locations = ["path/to/folder/a", "path/to/folder/b"]

#---> Code 

#does my path exist
if os.path.exists(jpg_index):
    #for-loop to check all given search locations
    for search_location in search_locations:
        #find paths ending with jpg
        for path in Path(search_location).rglob('*.jpg'):
            #Open the jpg_index so it can be scanned for matches
            with open(jpg_index, 'rb', 0) as file, \
                mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ) as s:
                    #proceed if no matches are found
                    if s.find(b'path') != -1:
                    #Open the index file / jpg list and append paths
                        with open(jpg_index, 'a') as filehandle:
                            filehandle.writelines('%s\n' % path)

我尝试了其他各种解决方案,例如在我开始使用 mmap 进行检查的地方改组,尽量避免使用 with open 两次,而且我确定它正在检查字符串 'path' 实际上并没有在看我的路径。

但是我经常没有收到任何错误消息,因此很难继续。显然它在工作,但不是我想要的那样。

#---> Modules (c&p from top of code)

import os
import pathlib
import glob, os
from pathlib import Path   
import os.path
from os import path
import mmap

编辑:

我也尝试实现了@skywallkee给出的答案,将代码改为:

if os.path.exists(jpg_index):
    for search_location in search_locations:
        for path in Path(search_location).rglob('*.jpg'):
            mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ) as s:
                if s.find(str.encode(path.__str__())) < 0:
                    with open(jpg_index, 'a') as filehandle:
                        filehandle.writelines('%s\n' % path)

然而,这给出了错误

    mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ) as s:
                                                         ^
SyntaxError: invalid syntax

我哪里错了? (我正在 Mac,将 Atom 与 Hydrogen 模块结合使用。)

编辑 2:

我删的太多了,skywallkee的解释很好,看他的Pastebin解法没有我的错误

请注意,使用 Atom 时,这似乎会失败,因为如果在选项卡中打开列表,列表不会展开。必须关闭并重新打开文本列表以观察进度。

那是因为您的代码将始终检查文件中是否存在以字节表示的“路径”,而这可能根本不存在。如果你想检查变量路径的内容是否在文件中,那么你可以这样做:

if s.find(str.encode(path.__str__())) < 0:
#Open the index file / jpg list and append paths
      with open(jpg_index, 'a') as filehandle:
            filehandle.writelines('%s\n' % path)

如果找到文件,s.find将给出一个正值,因此您要检查它是否小于0,以便您可以写入文件。如果您正在检查它是否是 != -1 那么您很可能永远不会写入文件,因为 s.find 将 return -1 因为找不到文件而您正在寻找是否 s.find != -1,这没有什么不同,所以你永远不会进入那个 if。只有当文件中已经有一些路径并且路径已经存在时,你才会进入它,这就是为什么你实际上会写两次路径并且从不写文件中不存在的路径的原因。

通过使用 str.encode("string"),您将字符串转换为字节,因此您实际上可以通过执行 str.encode(path.__str__()) 将路径转换为字节。您还需要调用 path.str() 因为 path 是 WindowsPath(如果您在 Windows 上 运行)所以您想要作为字符串的路径。