【问题标题】:What is fast way to check 'isDir' in python?在python中检查'isDir'的快速方法是什么?
【发布时间】:2021-07-09 14:44:14
【问题描述】:

在我的项目中,我的程序检查了很多目录和文件。

我使用 python 3.8。

首先,我试试这个。 下面是我的代码 sn-p。

if '.' not in filename:  # dir

我知道,这是不对的。 目录名可以包含'.'!

我试试这个。

if os.path.isdir(os.path.join(path_dir, filename)):  # dir

没错。 但是,上面的代码非常慢!

第一个代码使用 0.48 秒。但第二次使用 17 秒...

我更改 [os.path.join] -> [path_dir + '\' + 文件名]。 需要 15 秒。也太慢了。

我知道 os.path.isdir 有问题。下面是测试。

@logging_time
def test_func1(dir_name, file_name):
    full_path = os.path.join(dir_name, file_name)
    for i in range(100000):
        if os.path.isdir(full_path):
            res = 'a'


@logging_time
def test_func2(dir_name, file_name):
    for i in range(100000):
        if '.' not in file_name:
            res = 'a'

test_func2 只用了 0.003 秒,而 test_func1 用了 3 秒!

检查isDir的快速方法是什么?

目标操作系统是 windows 10。 我不需要跨平台。只是窗口。

【问题讨论】:

  • @joshmeranda 我找不到 os.is_dir() 。我需要导入一些包吗?
  • 你需要导入os
  • @joshmeranda 我已经导入了它。我现在使用 os.path.isdir。
  • @Redwings: test_func1test_func2 正在做完全不同的事情......

标签: python python-3.x windows


【解决方案1】:

也许检查某物是否是目录的最快方法是根本不必检查。 如果您希望迭代目录树中的所有文件(您实际上并没有指定是否是这种情况),您应该考虑使用os.walk

os.walk(top, topdown=True, onerror=None, followlinks=False)

通过自上而下或自下而上遍历目录树来生成目录树中的文件名。对于以目录 top 为根的树中的每个目录(包括 top 本身),它会产生一个 3 元组(dirpath、dirnames、filenames)。

元组的第三个元素 (filenames) 保证不是目录。这是在目录树中打印所有文件名的方式:

import os

def walk_directory(directory_name):
    for dirpath, dirnames, filenames in os.walk(directory_name):
        for filename in filenames:
            fullpathname = os.path.join(dirpath, filename)
            print(fullpathname)

否则,您应该使用isDir 方法调用。例如,如果您只想迭代单个目录中的所有文件,那么一种方法如下:

from pathlib import Path

def list_directory(directory_name):
    # non-recursive
    for p in Path(directory_name).glob('*'):
        if not p.is_dir():
            #filename = str(p) # to convert Path to a string
            print(p)

【讨论】:

  • 完美!!!这就是我要的!! os.walk 比 isDir 快 25 倍!感谢您的帮助!
【解决方案2】:

os.path.isdir 似乎是最快的实现:

from pathlib import Path
import os
import win32api
import glob
import timeit


def os_isDir(files):
    return [os.path.isdir(fullPath) for fullPath in files]

def os_NOT_isFile(files):
    return [not os.path.isfile(fullPath) for fullPath in files]

def pathlib_isDir(files):
    return [Path(fullPath).is_dir() for fullPath in files]

def winapi_GetFileAttributesA(files):
    return [win32api.GetFileAttributes(fullPath) == 16 for fullPath in files]


files = glob.glob('C:\\Windows\\System32\\*')
for func in ("os_isDir", "os_NOT_isFile", "pathlib_isDir", "winapi_GetFileAttributesA"):
    t1 = timeit.Timer(f"{func}({files})", f"from __main__ import {func}")
    print(f"Evaluation {len(files)} paths using {func} took: {t1.timeit(number=5)} seconds\n")

输出(在 Win7 虚拟机上):

Evaluation 3294 paths using os_isDir took: 2.1250754 seconds

Evaluation 3294 paths using os_NOT_isFile took: 2.7074766999999995 seconds

Evaluation 3294 paths using pathlib_isDir took: 3.4624453000000006 seconds

Evaluation 3294 paths using winapi_GetFileAttributesA took: 2.2789655999999994 seconds

【讨论】:

  • 这是个小不幸消息。感谢您的帮助。
猜你喜欢
  • 2012-05-20
  • 1970-01-01
  • 2019-01-10
  • 2020-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-23
相关资源
最近更新 更多