programing

Python에서 모든 서브디렉토리를 가져오는 방법

kingscode 2022. 10. 1. 20:44
반응형

Python에서 모든 서브디렉토리를 가져오는 방법

모든 서브디렉토리의 index.tpl을 index.html에 복사하는 간단한 Python 스크립트를 작성하려고 합니다(몇 가지 예외는 제외).

서브디렉토리 목록을 얻느라 꼼짝 못하고 있어.

import os
def get_immediate_subdirectories(a_dir):
    return [name for name in os.listdir(a_dir)
            if os.path.isdir(os.path.join(a_dir, name))]

현재 모든 서브디렉토리에 풀패스를 되돌리기 위해 다양한 기능에 대해 속도 테스트를 실시했습니다.

tl;dr: 항상 사용:

list_subfolders_with_paths = [f.path for f in os.scandir(path) if f.is_dir()]

보너스: 포함scandir또한 단순히 폴더 이름만 사용할 수 있습니다.f.name대신f.path.

이 기능(및 아래의 모든 기능)은 자연 정렬을 사용하지 않습니다.즉, 결과는 1, 10, 2와 같이 정렬됩니다.내추럴 정렬(1, 2, 10)은 https://stackoverflow.com/a/48030307/2441026을 참조하십시오.




결과:scandir의 3배 고속walk, 32배 고속listdir(필터 포함), 35배 고속Pathlib36배 빠른 속도listdir37배(!) 고속으로glob.

Scandir:           0.977
Walk:              3.011
Listdir (filter): 31.288
Pathlib:          34.075
Listdir:          35.501
Glob:             36.277

W7x64, Python 3.8.1에서 테스트 완료.440개의 하위 폴더가 있는 폴더.
혹시 모르니까listdiros.path.disp()를 두 번 실행하지 않음으로써 속도를 높일 수 있지만 기본적으로는 차이가 없습니다.

코드:

import os
import pathlib
import timeit
import glob

path = r"<example_path>"



def a():
    list_subfolders_with_paths = [f.path for f in os.scandir(path) if f.is_dir()]
    # print(len(list_subfolders_with_paths))


def b():
    list_subfolders_with_paths = [os.path.join(path, f) for f in os.listdir(path) if os.path.isdir(os.path.join(path, f))]
    # print(len(list_subfolders_with_paths))


def c():
    list_subfolders_with_paths = []
    for root, dirs, files in os.walk(path):
        for dir in dirs:
            list_subfolders_with_paths.append( os.path.join(root, dir) )
        break
    # print(len(list_subfolders_with_paths))


def d():
    list_subfolders_with_paths = glob.glob(path + '/*/')
    # print(len(list_subfolders_with_paths))


def e():
    list_subfolders_with_paths = list(filter(os.path.isdir, [os.path.join(path, f) for f in os.listdir(path)]))
    # print(len(list(list_subfolders_with_paths)))


def f():
    p = pathlib.Path(path)
    list_subfolders_with_paths = [x for x in p.iterdir() if x.is_dir()]
    # print(len(list_subfolders_with_paths))



print(f"Scandir:          {timeit.timeit(a, number=1000):.3f}")
print(f"Listdir:          {timeit.timeit(b, number=1000):.3f}")
print(f"Walk:             {timeit.timeit(c, number=1000):.3f}")
print(f"Glob:             {timeit.timeit(d, number=1000):.3f}")
print(f"Listdir (filter): {timeit.timeit(e, number=1000):.3f}")
print(f"Pathlib:          {timeit.timeit(f, number=1000):.3f}")

왜 아무도 언급하지 않았지?glob를 사용하면 Unix 스타일의 경로 이름 확장을 사용할 수 있으며, 여러 경로 이름을 찾아야 하는 거의 모든 작업에 사용할 수 있습니다.매우 간단합니다.

from glob import glob
paths = glob('*/')

주의:glob(유닉스와 마찬가지로) 마지막 슬래시를 포함한 디렉토리를 반환하는 반면,path베이스 솔루션에서는 마지막 슬래시가 생략됩니다.

"현재 디렉토리의 모든 하위 디렉토리 목록 가져오기"를 선택합니다.

다음은 Python 3 버전입니다.

import os

dir_list = next(os.walk('.'))[1]

print(dir_list)
import os

디렉토리의 즉시 서브 디렉토리를 취득(풀 패스)하려면 , 다음의 순서에 따릅니다.

def SubDirPath (d):
    return filter(os.path.isdir, [os.path.join(d,f) for f in os.listdir(d)])

최신(최신) 서브디렉토리를 취득하려면 , 다음의 순서에 따릅니다.

def LatestDirectory (d):
    return max(SubDirPath(d), key=os.path.getmtime)

os.walk 이 상황에서 당신의 친구입니다.

매뉴얼에서 직접:

walk()는 트리를 위에서 아래로 또는 위로 이동하여 디렉토리 트리의 파일 이름을 생성합니다.디렉토리 톱(상단 자체를 포함한다)에 루트 되는 트리내의 각 디렉토리에 대해서, 3-태플(dirpath, dirnames, 파일명)을 생성합니다.

이 방법은 한 번에 모든 것을 잘 해낼 수 있다.

from glob import glob
subd = [s.rstrip("/") for s in glob(parent_dir+"*/")]

Twisted의 FilePath 모듈 사용:

from twisted.python.filepath import FilePath

def subdirs(pathObj):
    for subpath in pathObj.walk():
        if subpath.isdir():
            yield subpath

if __name__ == '__main__':
    for subdir in subdirs(FilePath(".")):
        print "Subdirectory:", subdir

Twisted's Library를 사용하면 어떤 이점이 있는지 묻는 코멘트가 있기 때문에, 여기에서는 원래의 질문을 조금 넘어섭니다.


분기에는 FilePath의 장점을 설명하는 개선된 문서가 있습니다. 읽어보시기 바랍니다.

이 예에서는 보다 구체적으로 설명하겠습니다.표준 라이브러리 버전과 달리 이 함수는 Import 없이 구현할 수 있습니다."subdirs" 함수는 완전히 일반적이며 인수만 사용합니다.표준 라이브러리를 사용하여 파일을 복사 및 이동하려면 ""에 의존해야 합니다.open '빌트인', '빌트인',listdir " " " "" "" "" "isdir " " " " "os.walk " " " " "shutil.copy " " " " "os.path.join문자열이 필요하다는 사실은 말할 것도 없고 실제 파일을 식별하는 인수를 통과했습니다.을 「풀에 대해 .index.tpl은 index.html로 합니다.

def copyTemplates(topdir):
    for subdir in subdirs(topdir):
        tpl = subdir.child("index.tpl")
        if tpl.exists():
            tpl.copyTo(subdir.child("index.html"))

은 모든 "subdirs"에서 할 수 .FilePath-물체와 유사합니다.그 말은 다른 무엇보다도ZipPathately들 unfortun unfortun unfortun행ately unfortun행 불행불ZipPath현재 읽기 전용이지만 쓰기를 지원하도록 확장할 수 있습니다.

테스트 목적으로 사용자 자신의 개체를 전달할 수도 있습니다.여기서 제안하는 os.path-using API를 테스트하려면 Import된 이름과 암묵적인 의존관계를 사용하여 일반적으로 Black Magic을 실행하여 테스트를 실행해야 합니다.FilePath에서는 다음과 같은 작업을 수행합니다.

class MyFakePath:
    def child(self, name):
        "Return an appropriate child object"

    def walk(self):
        "Return an iterable of MyFakePath objects"

    def exists(self):
        "Return true or false, as appropriate to the test"

    def isdir(self):
        "Return true or false, as appropriate to the test"
...
subdirs(MyFakePath(...))

인데, VMware를 .os.path ★★★★★★★★★★★★★★★★★」shutil이치노

def copy_client_files (file_src, file_dst):
    for file in os.listdir(file_src):
            print "Copying file: %s" % file
            shutil.copy(os.path.join(file_src, file), os.path.join(file_dst, file))

아주 우아하진 않지만 효과가 있어요.

한 가지 방법이 있습니다.

import os
import shutil

def copy_over(path, from_name, to_name):
  for path, dirname, fnames in os.walk(path):
    for fname in fnames:
      if fname == from_name:
        shutil.copy(os.path.join(path, from_name), os.path.join(path, to_name))


copy_over('.', 'index.tpl', 'index.html')

제가 자주 사용하는 path.py 라이브러리를 언급해야 합니다.

즉시 서브 디렉토리를 취득하는 것은 다음과 같이 간단합니다.

my_dir.dirs()

완전한 작업 예를 다음에 나타냅니다.

from path import Path

my_directory = Path("path/to/my/directory")

subdirs = my_directory.dirs()

NB: my_directory는 문자열의 서브클래스로 조작할 수 있지만 경로를 조작하기 위한 유용한 메서드를 많이 제공합니다.

def get_folders_in_directories_recursively(directory, index=0):
    folder_list = list()
    parent_directory = directory

    for path, subdirs, _ in os.walk(directory):
        if not index:
            for sdirs in subdirs:
                folder_path = "{}/{}".format(path, sdirs)
                folder_list.append(folder_path)
        elif path[len(parent_directory):].count('/') + 1 == index:
            for sdirs in subdirs:
                folder_path = "{}/{}".format(path, sdirs)
                folder_list.append(folder_path)

    return folder_list

다음 함수는 다음과 같이 호출할 수 있습니다.

get_directories_in_directories_directoryly(디렉토리, 인덱스=1) ->는 첫 번째 수준의 폴더 목록을 제공합니다.

get_syslog_in_directories_syslogly(디렉토리) ->는 모든 서브폴더를 제공합니다.

import glob
import os

def child_dirs(path):
     cd = os.getcwd()        # save the current working directory
     os.chdir(path)          # change directory 
     dirs = glob.glob("*/")  # get all the subdirectories
     os.chdir(cd)            # change directory to the script original location
     return dirs

child_dirsfunction은 경로를 디렉토리로 지정하고 디렉토리 내의 즉시 하위 디렉토리의 목록을 반환합니다.

dir
 |
  -- dir_1
  -- dir_2

child_dirs('dir') -> ['dir_1', 'dir_2']
import pathlib


def list_dir(dir):
    path = pathlib.Path(dir)
    dir = []
    try:
        for item in path.iterdir():
            if item.is_dir():
                dir.append(item)
        return dir
    except FileNotFoundError:
        print('Invalid directory')

pathlib을 사용하는 라이너 1개:

list_subfolders_with_paths = [p for p in pathlib.Path(path).iterdir() if p.is_dir()]

언급URL : https://stackoverflow.com/questions/800197/how-to-get-all-of-the-immediate-subdirectories-in-python

반응형