python 확인 디렉토리의 모든 파일을 나열하려면 어떻게합니까?




파이썬 파일 불러 오기 (24)

파일 목록 만 가져 오는 한 줄 솔루션 (하위 디렉토리 없음) :

filenames = next(os.walk(path))[2]

또는 절대 경로 이름 :

paths = [os.path.join(path,fn) for fn in next(os.walk(path))[2]]

파이썬에서 디렉토리의 모든 파일을 list 하고 list 추가하려면 어떻게합니까?


절대 파일 경로 목록 반환, 하위 디렉토리로 재귀하지 않음

L = [os.path.join(os.getcwd(),f) for f in os.listdir('.') if os.path.isfile(os.path.join(os.getcwd(),f))]

원본 경로와 파일 형식을 입력으로 제공 할 수있는 샘플 라이너를 제공합니다. 이 코드는 csv 확장자를 가진 파일 이름 목록을 반환합니다. 사용 . 모든 파일을 반환해야하는 경우에 사용합니다. 또한 서브 디렉토리를 재귀 적으로 스캔합니다.

[y for x in os.walk(sourcePath) for y in glob(os.path.join(x[0], '*.csv'))]

필요에 따라 파일 확장자 및 소스 경로를 수정하십시오.


디렉토리의 모든 파일 나열 :

import os
from os import path

files = [x for x in os.listdir(directory_path) if path.isfile(directory_path+os.sep+x)]

여기에서는 디렉토리의 모든 파일 목록을 얻습니다.


다른 파일 형식을 사용하거나 전체 디렉토리를 가져 오려면이 기능을 사용하십시오.

import os

def createList(foldername, fulldir = True, suffix=".jpg"):
    file_list_tmp = os.listdir(foldername)
    #print len(file_list_tmp)
    file_list = []
    if fulldir:
        for item in file_list_tmp:
            if item.endswith(suffix):
                file_list.append(os.path.join(foldername, item))
    else:
        for item in file_list_tmp:
            if item.endswith(suffix):
                file_list.append(item)
    return file_list

os.listdir() 은 디렉토리에있는 모든 것을 가져옵니다 - 파일과 디렉토리.

파일 원한다면 os.path 사용하여 이것을 필터링 할 수 있습니다.

from os import listdir
from os.path import isfile, join
onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))]

또는 os.walk() 를 사용하여 방문하는 각 디렉토리에 대해 파일과 디렉토리로 분할하는 두 개의 목록을 생성 할 수 있습니다. 최상위 디렉토리 만 원할 경우 처음으로 생성되는 디렉토리를 중단 할 수 있습니다.

from os import walk

f = []
for (dirpath, dirnames, filenames) in walk(mypath):
    f.extend(filenames)
    break

그리고 마지막으로,이 예제에서 보여 주듯이 하나의 목록을 다른 목록에 추가하면 .extend() 또는

>>> q = [1, 2, 3]
>>> w = [4, 5, 6]
>>> q = q + w
>>> q
[1, 2, 3, 4, 5, 6]

개인적으로, 나는 .extend()


정말 간단한 버전 :

import os
[f for f in os.listdir(os.getcwd) if ...]

11

예비 사항

  • 질문 텍스트에는 파일디렉토리 용어가 명확하게 구분되어 있지만 일부는 디렉토리가 실제로 특수 파일이라고 주장 할 수 있습니다
  • " 디렉토리의 모든 파일 "은 다음과 같은 두 가지 방식으로 해석 될 수 있습니다.
    1. 모든 직접 (또는 레벨 1) 자손
    2. 전체 디렉토리 트리에있는 모든 하위 항목 (하위 디렉토리에있는 항목 포함)
  • 질문을 받았을 때, Python 2LTS 버전이라고 상상했지만 코드 샘플은 Python 3 ( .5 )에서 실행됩니다 ( 가능한 한 Python 2 호환으로 유지할 것입니다. 내가 게시 할 파이썬 은 별도로 명시하지 않는 한 v3.5.4 버전 입니다.) 그 질문에 또 다른 키워드와 관련된 결과가 있습니다 : " 목록에 추가 ":

    • Python 2.2 이전 버전에서는 시퀀스 (iterables)가 대부분 목록 (튜플, 세트 등)으로 나타났습니다.
    • Python 2.2 에서 generator ( [Python] : Generators )의 개념 - [Python]의 호의 : yield 문 )이 소개되었습니다. 시간이 지남에 따라 생성자가 목록을 반환 / 작업 한 함수에 대해 표시되기 시작했습니다.
    • 파이썬 3 에서는 생성자가 기본 동작입니다.
    • 지금, 나는 목록을 반환하는 것이 여전히 의무적인지 (또는 생성자가 잘 할 것인지는) 모르겠지만 생성자를 list 생성자에 전달하면 list 을 생성하고 소비 할 수도있다. 아래 예제는 [Python] 의 차이점을 보여줍니다 : map ( function, iterable, ... )
    Python 2.7.10 (default, Mar  8 2016, 15:02:46) [MSC v.1600 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> m = map(lambda x: x, [1, 2, 3])  # Just a dummy lambda function
    >>> m, type(m)
    ([1, 2, 3], <type 'list'>)
    >>> len(m)
    3
    


    Python 3.5.4 (v3.5.4:3f56838, Aug  8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> m = map(lambda x: x, [1, 2, 3])
    >>> m, type(m)
    (<map object at 0x000001B4257342B0>, <class 'map'>)
    >>> len(m)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: object of type 'map' has no len()
    >>> lm0 = list(m)  # Construct a list out of the generator
    >>> lm0, type(lm0)
    ([1, 2, 3], <class 'list'>)
    >>>
    >>> lm1 = list(m)  # Construct a list out of the same generator
    >>> lm1, type(lm1)  # Empty list this time - generator already consumed
    ([], <class 'list'>)
    
  • 예제는 다음 구조를 가진 root_dir 이라는 디렉토리를 기반으로합니다 (이 예제는 Windows 용이지만 Ux ( Lnx ) 폴더 트리도 복제했습니다).

    E:\Work\Dev\\q003207219>tree /f "root_dir"
    Folder PATH listing for volume Work
    Volume serial number is 00000029 3655:6FED
    E:\WORK\DEV\\Q003207219\ROOT_DIR
    │   file0
    │   file1
    │
    ├───dir0
    │   ├───dir00
    │   │   │   file000
    │   │   │
    │   │   └───dir000
    │   │           file0000
    │   │
    │   ├───dir01
    │   │       file010
    │   │       file011
    │   │
    │   └───dir02
    │       └───dir020
    │           └───dir0200
    ├───dir1
    │       file10
    │       file11
    │       file12
    │
    ├───dir2
    │   │   file20
    │   │
    │   └───dir20
    │           file200
    │
    └───dir3
    


솔루션

프로그래밍 방식 :

  1. [파이썬] : os. listdir ( 경로 = '.' )

    path에 의해 주어진 디렉토리에있는 엔트리의 이름을 담고있는리스트를 반환한다. 목록은 임의의 순서로 있으며 특수 항목 '.' 포함하지 않습니다 '.' '..'


    >>> import os
    >>> root_dir = "root_dir"  # Path relative to current dir (os.getcwd())
    >>>
    >>> os.listdir(root_dir)  # List all the items in root_dir
    ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1']
    >>>
    >>> [item for item in os.listdir(root_dir) if os.path.isfile(os.path.join(root_dir, item))]  # Filter the items and only keep files (strip out directories)
    ['file0', 'file1']
    

    다음은 좀 더 정교한 예제입니다 ( code_os_listdir.py ).

    import os
    from pprint import pformat
    
    
    def _get_dir_content(path, include_folders, recursive):
        entries = os.listdir(path)
        for entry in entries:
            entry_with_path = os.path.join(path, entry)
            if os.path.isdir(entry_with_path):
                if include_folders:
                    yield entry_with_path
                if recursive:
                    for sub_entry in _get_dir_content(entry_with_path, include_folders, recursive):
                        yield sub_entry
            else:
                yield entry_with_path
    
    
    def get_dir_content(path, include_folders=True, recursive=True, prepend_folder_name=True):
        path_len = len(path) + len(os.path.sep)
        for item in _get_dir_content(path, include_folders, recursive):
            yield item if prepend_folder_name else item[path_len:]
    
    
    def _get_dir_content_old(path, include_folders, recursive):
        entries = os.listdir(path)
        ret = list()
        for entry in entries:
            entry_with_path = os.path.join(path, entry)
            if os.path.isdir(entry_with_path):
                if include_folders:
                    ret.append(entry_with_path)
                if recursive:
                    ret.extend(_get_dir_content_old(entry_with_path, include_folders, recursive))
            else:
                ret.append(entry_with_path)
        return ret
    
    
    def get_dir_content_old(path, include_folders=True, recursive=True, prepend_folder_name=True):
        path_len = len(path) + len(os.path.sep)
        return [item if prepend_folder_name else item[path_len:] for item in _get_dir_content_old(path, include_folders, recursive)]
    
    
    def main():
        root_dir = "root_dir"
        ret0 = get_dir_content(root_dir, include_folders=True, recursive=True, prepend_folder_name=True)
        lret0 = list(ret0)
        print(ret0, len(lret0), pformat(lret0))
        ret1 = get_dir_content_old(root_dir, include_folders=False, recursive=True, prepend_folder_name=False)
        print(len(ret1), pformat(ret1))
    
    
    if __name__ == "__main__":
        main()
    

    참고 사항 :

    • 두 가지 구현이 있습니다.
      • 하나는 발전기를 사용합니다 (물론이 예제에서는 결과를 목록으로 즉시 변환하므로 쓸모없는 것처럼 보입니다)
      • 고전적인 것 ( _old로 끝나는 함수 이름)
    • 재귀가 사용됩니다 (하위 디렉토리로 이동).
    • 각 구현에는 두 가지 기능이 있습니다.
      • 밑줄 ( _ )로 시작하는 하나 : "개인"(직접 호출해서는 안 됨) - 모든 작업을 수행합니다.
      • 공개 된 것 (이전의 래퍼) : 리턴 된 엔트리에서 초기 경로 (필요한 경우)를 제거합니다. 못생긴 구현이지만,이 시점에서 내가 올 수있는 유일한 아이디어입니다.
    • 성능 측면에서 생성자는 일반적으로 조금 더 빠르며 ( 생성반복 시간 모두 고려) 재귀 함수로 테스트하지 않았고 내부 생성기를 통해 함수 내부를 반복합니다. 우호적이다.
    • 인수를 사용하여 다른 결과 얻기


    출력 :

    (py35x64_test) E:\Work\Dev\\q003207219>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" "code_os_listdir.py"
    <generator object get_dir_content at 0x000001BDDBB3DF10> 22 ['root_dir\\dir0',
     'root_dir\\dir0\\dir00',
     'root_dir\\dir0\\dir00\\dir000',
     'root_dir\\dir0\\dir00\\dir000\\file0000',
     'root_dir\\dir0\\dir00\\file000',
     'root_dir\\dir0\\dir01',
     'root_dir\\dir0\\dir01\\file010',
     'root_dir\\dir0\\dir01\\file011',
     'root_dir\\dir0\\dir02',
     'root_dir\\dir0\\dir02\\dir020',
     'root_dir\\dir0\\dir02\\dir020\\dir0200',
     'root_dir\\dir1',
     'root_dir\\dir1\\file10',
     'root_dir\\dir1\\file11',
     'root_dir\\dir1\\file12',
     'root_dir\\dir2',
     'root_dir\\dir2\\dir20',
     'root_dir\\dir2\\dir20\\file200',
     'root_dir\\dir2\\file20',
     'root_dir\\dir3',
     'root_dir\\file0',
     'root_dir\\file1']
    11 ['dir0\\dir00\\dir000\\file0000',
     'dir0\\dir00\\file000',
     'dir0\\dir01\\file010',
     'dir0\\dir01\\file011',
     'dir1\\file10',
     'dir1\\file11',
     'dir1\\file12',
     'dir2\\dir20\\file200',
     'dir2\\file20',
     'file0',
     'file1']
    


  1. [파이썬] : os. scandir ( path = '.' ) ( !!! 파이썬 3.5 + !!! 이전 버전의 경우 파이썬 2 로 포팅 된 별도의 모듈이라고 생각하지만)

    path로 지정된 디렉토리 내의 엔트리에 대응하는 os.DirEntry 객체의 반복자를 돌려줍니다. 항목은 임의의 순서로 생성되고 특수 항목 '.''..' 는 포함되지 않습니다.

    listdir () 대신 scandir ()을 사용하면 운영 체제가 디렉토리를 검색 할 때 os.DirEntry 객체가이 정보를 노출하므로 파일 유형이나 파일 속성 정보가 필요한 코드의 성능을 크게 향상시킬 수 있습니다. 모든 os.DirEntry 메서드는 시스템 호출을 수행 할 수 있지만 is_dir()is_file() 대개 심볼릭 링크에 대한 시스템 호출 만 필요로합니다. os.DirEntry.stat() 는 Unix에서는 항상 시스템 호출이 필요하지만 Windows의 심볼릭 링크에만 필요합니다.


    >>> import os
    >>> root_dir = os.path.join(".", "root_dir")  # Explicitly prepending current directory
    >>> root_dir
    '.\\root_dir'
    >>>
    >>> scandir_iterator = os.scandir(root_dir)
    >>> scandir_iterator
    <nt.ScandirIterator object at 0x00000268CF4BC140>
    >>> [item.path for item in scandir_iterator]
    ['.\\root_dir\\dir0', '.\\root_dir\\dir1', '.\\root_dir\\dir2', '.\\root_dir\\dir3', '.\\root_dir\\file0', '.\\root_dir\\file1']
    >>>
    >>> [item.path for item in scandir_iterator]  # Will yield an empty list as it was consumed by previous iteration (automatically performed by the list comprehension)
    []
    >>>
    >>> scandir_iterator = os.scandir(root_dir)  # Reinitialize the generator
    >>> for item in scandir_iterator :
    ...     if os.path.isfile(item.path):
    ...             print(item.name)
    ...
    file0
    file1
    

    참고 사항 :

    • os.listdir 과 비슷합니다.
    • 하지만 또한 더 유연하고 (더 많은 기능을 제공합니다), 더 많은 파이썬 ic (어떤 경우에는 더 빠름)


  1. [파이썬] : os. 도보 ( top, topdown = True, onerror = 없음, followlinks = False )

    트리를 하향식 또는 상향식으로 이동하여 디렉토리 트리에서 파일 이름을 생성하십시오. 최상위 디렉토리를 루트로하는 트리의 각 디렉토리에 대해 3-tuple ( dirpath , dirnames , filenames )을 생성합니다.


    >>> import os
    >>> root_dir = os.path.join(os.getcwd(), "root_dir")  # Specify the full path
    >>> root_dir
    'E:\\Work\\Dev\\\\q003207219\\root_dir'
    >>>
    >>> walk_generator = os.walk(root_dir)
    >>> root_dir_entry = next(walk_generator)  # First entry corresponds to the root dir (that was passed as an argument)
    >>> root_dir_entry
    ('E:\\Work\\Dev\\\\q003207219\\root_dir', ['dir0', 'dir1', 'dir2', 'dir3'], ['file0', 'file1'])
    >>>
    >>> root_dir_entry[1] + root_dir_entry[2]  # Display the dirs and the files (that are direct descendants) in a single list
    ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1']
    >>>
    >>> [os.path.join(root_dir_entry[0], item) for item in root_dir_entry[1] + root_dir_entry[2]]  # Display all the entries in the previous list by their full path
    ['E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0', 'E:\\Work\\Dev\\\\q003207219\\root_dir\\dir1', 'E:\\Work\\Dev\\\\q003207219\\root_dir\\dir2', 'E:\\Work\\Dev\\\\q003207219\\root_dir\\dir3', 'E:\\Work\\Dev\\\\q003207219\\root_dir\\file0', 'E:\\Work\\Dev\\\\q003207219\\root_dir\\file1']
    >>>
    >>> for entry in walk_generator:  # Display the rest of the elements (corresponding to every subdir)
    ...     print(entry)
    ...
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0', ['dir00', 'dir01', 'dir02'], [])
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0\\dir00', ['dir000'], ['file000'])
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0\\dir00\\dir000', [], ['file0000'])
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0\\dir01', [], ['file010', 'file011'])
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0\\dir02', ['dir020'], [])
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0\\dir02\\dir020', ['dir0200'], [])
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir0\\dir02\\dir020\\dir0200', [], [])
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir1', [], ['file10', 'file11', 'file12'])
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir2', ['dir20'], ['file20'])
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir2\\dir20', [], ['file200'])
    ('E:\\Work\\Dev\\\\q003207219\\root_dir\\dir3', [], [])
    

    참고 사항 :

    • 장면 아래에서 os.listdir( 사용 os.scandir가능한 경우)
    • 하위 폴더에서 되풀이하여 무거운 짐을 덜어줍니다.


  1. [파이썬] : glob. glob ( pathname, *, recursive = False ) ( [Python] : glob. iglob ( 경로 이름, *, 재귀 = False ) )

    pathname 에 일치하는 공백 일 가능성이있는 패스 명을 돌려줍니다. 패스 명은, 패스 명을 포함한 캐릭터 라인이 아니면 안됩니다. pathname 은 absolute (like /usr/src/Python-1.5/Makefile) 또는 relative (like ../../Tools/*/*.gif) 중 하나 일 수 있으며 쉘 스타일 와일드 카드를 포함 할 수 있습니다. 깨진 심볼릭 링크가 결과에 포함됩니다 (셸과 마찬가지로).
    ...
    버전 3.5에서 변경되었습니다 : "**"을사용하여 재귀 적 glob을 지원합니다.


    >>> import glob, os
    >>> wildcard_pattern = "*"
    >>> root_dir = os.path.join("root_dir", wildcard_pattern)  # Match every file/dir name
    >>> root_dir
    'root_dir\\*'
    >>>
    >>> glob_list = glob.glob(root_dir)
    >>> glob_list
    ['root_dir\\dir0', 'root_dir\\dir1', 'root_dir\\dir2', 'root_dir\\dir3', 'root_dir\\file0', 'root_dir\\file1']
    >>>
    >>> [item.replace("root_dir" + os.path.sep, "") for item in glob_list]  # Strip the dir name and the path separator from begining
    ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1']
    >>>
    >>> for entry in glob.iglob(root_dir + "*", recursive=True):
    ...     print(entry)
    ...
    root_dir\
    root_dir\dir0
    root_dir\dir0\dir00
    root_dir\dir0\dir00\dir000
    root_dir\dir0\dir00\dir000\file0000
    root_dir\dir0\dir00\file000
    root_dir\dir0\dir01
    root_dir\dir0\dir01\file010
    root_dir\dir0\dir01\file011
    root_dir\dir0\dir02
    root_dir\dir0\dir02\dir020
    root_dir\dir0\dir02\dir020\dir0200
    root_dir\dir1
    root_dir\dir1\file10
    root_dir\dir1\file11
    root_dir\dir1\file12
    root_dir\dir2
    root_dir\dir2\dir20
    root_dir\dir2\dir20\file200
    root_dir\dir2\file20
    root_dir\dir3
    root_dir\file0
    root_dir\file1
    

    참고 사항 :

    • 용도 os.listdir
    • 큰 나무의 경우 (특히 recursive켜져있는 경우 ) iglob선호됩니다.
    • 이름에 기반한 고급 필터링 허용 (와일드 카드로 인해)


  1. [Python] : 클래스 pathlib. 경로 ( * pathsegments ) ( !!! 파이썬 3 + !!! backported 경우 모르겠다)

    >>> import pathlib
    >>> root_dir = "root_dir"
    >>> root_dir_instance = pathlib.Path(root_dir)
    >>> root_dir_instance
    WindowsPath('root_dir')
    >>> root_dir_instance.name
    'root_dir'
    >>> root_dir_instance.is_dir()
    True
    >>>
    >>> [item.name for item in root_dir_instance.glob("*")]  # Wildcard searching for all direct descendants
    ['dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1']
    >>>
    >>> [os.path.join(item.parent.name, item.name) for item in root_dir_instance.glob("*") if not item.is_dir()]  # Display paths (including parent) for files only
    ['root_dir\\file0', 'root_dir\\file1']
    

    참고 사항 :

    • 이것이 우리의 목표를 달성하는 한 가지 방법입니다.
    • 경로를 처리 하는 것은 OOP 스타일입니다.
    • 많은 기능을 제공합니다.


  1. [파이썬] : dircache.listdir (경로) ( !!! 파이썬 3 에서 제거됨 !!! )

    • 그러나 $ {PYTHON_SRC_DIR} /Lib/dircache.py : ~ # 20 + ( v2.7.14 부터 )에 따르면, 그것은 (thin) 래퍼 일뿐입니다.os.listdir


    def listdir(path):
        """List directory contents, using cache."""
        try:
            cached_mtime, list = cache[path]
            del cache[path]
        except KeyError:
            cached_mtime, list = -1, []
        mtime = os.stat(path).st_mtime
        if mtime != cached_mtime:
            list = os.listdir(path)
            list.sort()
        cache[path] = mtime, list
        return list
    


  1. [사람] :했던 opendir (3) / [사람] : READDIR (3) / [사람] : CLOSEDIR (3) 를 통해 [파이썬] :하는 ctypes - 파이썬에 대한 외국인 함수 라이브러리 ( ! UX는 특정 !!! )

    ctypes 는 Python을위한 외국 함수 라이브러리입니다. C 호환 데이터 유형을 제공하며 DLL 또는 공유 라이브러리에서 호출 함수를 사용할 수 있습니다. 이 라이브러리를 순수 Python으로 랩핑하는 데 사용할 수 있습니다.

    code_ctypes.py :

    #!/usr/bin/env python3
    
    import sys
    from ctypes import Structure, \
        c_ulonglong, c_longlong, c_ushort, c_ubyte, c_char, c_int, \
        CDLL, POINTER, \
        create_string_buffer, get_errno, set_errno, cast, sizeof
    
    
    DT_DIR = 4
    DT_REG = 8
    
    char256 = c_char * 256
    
    class LinuxDirent64(Structure):
        _fields_ = [
            ("d_ino", c_ulonglong),
            ("d_off", c_longlong),
            ("d_reclen", c_ushort),
            ("d_type", c_ubyte),
            ("d_name", char256),
        ]
    
    LinuxDirent64Ptr = POINTER(LinuxDirent64)
    
    libc_dll = CDLL(None)
    opendir = libc_dll.opendir
    readdir = libc_dll.readdir
    closedir = libc_dll.closedir
    libc_dll.__errno_location.restype = POINTER(c_int)
    errno_loc_func = libc_dll.__errno_location
    
    
    def _get_errno():
        return "errno: {:d}({:d})".format(get_errno(), errno_loc_func().contents.value)
    
    
    def get_dir_content(path):
        ret = [path, list(), list()]
        dir_stream = opendir(create_string_buffer(path.encode()))
        if (dir_stream == 0):
            print("opendir returned NULL ({:s})".format(_get_errno()))
            return ret
        set_errno(0)
        dirent_addr = readdir(dir_stream)
        while dirent_addr:
            dirent_ptr = cast(dirent_addr, LinuxDirent64Ptr)
            dirent = dirent_ptr.contents
            name = dirent.d_name.decode()
            if dirent.d_type & DT_DIR:
                if name not in (".", ".."):
                    ret[1].append(name)
            elif dirent.d_type & DT_REG:
                ret[2].append(name)
            dirent_addr = readdir(dir_stream)
        if get_errno() or errno_loc_func().contents.value:
            print("readdir returned NULL ({:s})".format(_get_errno()))
        closedir(dir_stream)
        return ret
    
    
    def main():
        print("{:s} on {:s}\n".format(sys.version, sys.platform))
        root_dir = "root_dir"
        entries = get_dir_content(root_dir)
        print(entries)
    
    
    if __name__ == "__main__":
        main()
    

    참고 사항 :

    • 그것은에서 세 가지 기능로드 의 libc (현재 프로세스에로드를) 및 자세한 내용 확인을 위해 (그들을 호출 [스택 오버플로] : 어떻게 파일이 파이썬을 사용하여 존재하는지 여부를 확인합니까 () CristiFati의 대답 @? - 항목에서 마지막 노트 # 4 . ). 이 접근법은 Python / C edge에 매우 가깝습니다.
    • LinuxDirent64내 컴퓨터 에서 dirent.h ( 상수) 의 ctypes 표현 입니다 : Ubtu 16 x64 ( 4.10.0-40-genericlibc6-dev : amd64 ). 다른 버전 / 버전에서는 구조체 정의가 다를 수 있으며, 그렇다면 ctypes 별칭이 업데이트되어야합니다. 그렇지 않으면 정의되지 않은 동작이 발생합니다struct dirent64DT_*
    • errno_loc_func(그리고 그것과 관련된 모든 것)은 errno오류가 발생했을 때 funcs가 설정 되어 있기 때문에 그 값을 확인해야합니다. 분명히 get_errno작동하지 않습니다 (잘못된 이름으로 opendir반환 NULL하지만 get_errno여전히 0을 반환합니다). 또는 아직 이해하지 못했습니다.
    • 그것은 os.walk형식으로 데이터를 반환 합니다. 재귀 적으로 만들지는 않았지만 기존 코드부터 시작하면 상당히 사소한 작업이됩니다.
    • 모든 것은 Win 에서도 가능합니다. 데이터 (라이브러리, 함수, 구조체, 상수 등)는 다릅니다.


    출력 :

    [email protected]:~/work//q003207219$ ./code_ctypes.py
    3.5.2 (default, Nov 23 2017, 16:37:01)
    [GCC 5.4.0 20160609] on linux
    
    ['root_dir', ['dir3', 'dir2', 'dir0', 'dir1'], ['file0', 'file1']]
    


  1. [ActiveState] : win32file.FindFilesW ( !!! Win 특유의 !!! )

    Windows 유니 코드 API를 사용하여 일치하는 파일 이름의 목록을 검색합니다. API FindFirstFileW / FindNextFileW / Find close 함수에 대한 인터페이스.


    >>> import os, win32file, win32con
    >>> root_dir = "root_dir"
    >>> wildcard = "*"
    >>> root_dir_wildcard = os.path.join(root_dir, wildcard)
    >>> entry_list = win32file.FindFilesW(root_dir_wildcard)
    >>> len(entry_list)  # Don't display the whole content as it's too long
    8
    >>> [entry[-2] for entry in entry_list]  # Only display the entry names
    ['.', '..', 'dir0', 'dir1', 'dir2', 'dir3', 'file0', 'file1']
    >>>
    >>> [entry[-2] for entry in entry_list if entry[0] & win32con.FILE_ATTRIBUTE_DIRECTORY and entry[-2] not in (".", "..")]  # Filter entries and only display dir names (except self and parent)
    ['dir0', 'dir1', 'dir2', 'dir3']
    >>>
    >>> [os.path.join(root_dir, entry[-2]) for entry in entry_list if entry[0] & (win32con.FILE_ATTRIBUTE_NORMAL | win32con.FILE_ATTRIBUTE_ARCHIVE)]  # Only display file "full" names
    ['root_dir\\file0', 'root_dir\\file1']
    

    참고 사항 :


  1. 트릭을 수행하는 타사 패키지를 설치하십시오.
    • 대부분의 경우 위의 항목 중 하나 이상에 의존합니다 (약간의 맞춤 설정이 필요할 수 있음).


메모 (위의 내용에 대해) :

  • 코드는 이식 가능합니다 (특정 지역을 타겟팅하는 장소 - 표시된 곳 제외) 또는 교차 :
    • 플랫폼 ( Ux , Win ,)
    • 파이썬 버전 (2, 3,)
  • 위의 변형에서 여러 경로 스타일 (절대, 친척)을 사용하여 "도구"가이 방향에서 유연하다는 사실을 보여줍니다.
  • os.listdiros.scandir사용 opendir/ readdir/ closedir( [MSDN] FindFirstFile을 함수 / [MSDN] FindNextFile과 기능 / [MSDN] FindClose 함수 () "를 통해 $ {} PYTHON_SRC_DIR /Modules/posixmodule.c ")
  • win32file.FindFilesW( Win 고유의) 함수도 사용합니다 ( " $ {PYWIN32_SRC_DIR} /win32/src/win32file.i "를 통해).
  • get_dir_content(포인트 # 1에서 ) 이러한 접근 방법 중 하나를 사용하여 구현할 수 있습니다 (일부는 더 많은 작업과 약간의 작업이 필요합니다)
    • (단지 파일 대신 일부 고급 필터링 DIR)을 수행 할 수있는 다음 예를 들어 include_folders인수가 다른 (예에 의해 대체 될 수 filter_func: 인수로 경로를 취하는 함수 것) filter_func=lambda x: True(이 밖으로 제거하지 않습니다 아무것도) 내부 get_dir_content같은 : if not filter_func(entry_with_path): continue(함수가 하나 개의 항목에 대한 실패 할 경우, 그것은 건너 뜁니다),하지만 코드가되고 더 복잡한, 더 이상은 걸릴 것입니다 실행하기
  • 주의! 재귀가 사용 되었기 때문에 필자는 랩톱 ( Win 10 x64 )에서이 문제와 전혀 관련이없는 테스트를 거쳤 으며 재귀 수준이 (990 .. 1000) 범위 의 값에 도달했을 때 ( recursionlimit - 1000 (기본값)), 난 있어 :). 디렉토리 트리가 제한을 초과하면 ( FS 전문가가 아니기 때문에 가능한지 여부를 알 수 없으므로) 문제가 될 수 있습니다.
    또한 이 영역에 대한 경험이 없기 때문에 재귀 제한 을 늘리지 않으려 고합니다 ( 운영 체제 에서 스택을 늘리지 않고도 얼마를 늘릴 수 있습니까?레벨)이지만 이론적으로는 dir depth가 가능한 가장 높은 recursionlimit (해당 시스템에서) 보다 클 경우 항상 실패 할 가능성이 있습니다.
  • 코드 샘플은 설명의 목적으로 만 사용됩니다. 그게 내가 (내가 어떤 생각하지 않는 처리 계정 오류를 고려하지 않았 음을 의미합니다 try/ except/ else/ finally(: 간단하고 가능한 한 짧게 유지하는 이유는) 코드가 강력한되지 않도록, 블록). 들어 생산 , 오류 처리도 추가되어야한다

1 부 끝 1


1. Home 의 게시물 (질문 / 답변) 한도가 30000 자 ( [SE.Meta] : 귀하의 한계 파악 : 질문 제목, 게시물, 이미지 및 사용 된 링크의 최대 길이는 얼마입니까? )라는 사실 때문에, 대답은 2 부분으로 나누어 져 있습니다. [SO]를 방문하십시오 : 디렉토리의 모든 파일을 나열하려면 어떻게합니까? (@ CristiFati의 대답 - "2 부") .


퍼포먼스에 신경 쓰면 시도해보십시오 scandir. Python 2.x에서는 수동으로 설치해야 할 수도 있습니다. 예 :

# python 2.x
import scandir
import sys

de = scandir.scandir(sys.argv[1])
while 1:
    try:
        d = de.next()
        print d.path
    except StopIteration as _:
        break

이렇게하면 거대한 디렉토리를 스캔해야 할 때 많은 시간을 절약 할 수 있으며 큰 목록을 버퍼링 할 필요가 없으며 하나씩 가져와야합니다. 또한 재귀 적으로 할 수 있습니다.

def scan_path(path):
    de = scandir.scandir(path)
    while 1:
        try:
            e = de.next()
            if e.is_dir():
                scan_path(e.path)
            else:
                print e.path
        except StopIteration as _:
                break

파이썬 3.4+에서 또 다른 매우 읽기 쉬운 변형은 pathlib.Path.glob를 사용하고 있습니다 :

from pathlib import Path
folder = '/foo'
[f for f in Path(folder).glob('*') if f.is_file()]

좀 더 구체적으로 작성하는 것은 간단합니다. 예를 들어 심볼릭 링크가 아닌 파이썬 소스 파일을 모든 서브 디렉토리에서 찾습니다.

[f for f in Path(folder).glob('**/*.py') if not f.is_symlink()]

@adamk의 대답을 참고하면, @Anti Earth의 슬래시 불일치 코멘트에 대한 응답으로 내 OS 탐지 방법 이 있습니다.

import sys
import os
from pathlib import Path
from glob import glob
platformtype = sys.platform
if platformtype == 'win32':
    slash = "\\"
if platformtype == 'darwin':
    slash = "/"

# TODO: How can I list all files of a directory in Python and add them to a list?

# Step 1 - List all files of a directory

# Method 1: Find only pre-defined filetypes (.txt) and no subfiles, answer provided by @adamk
dir1 = "%sfoo%sbar%s*.txt" % (slash)
_files = glob(dir1)

# Method 2: Find all files and no subfiles
dir2 = "%sfoo%sbar%s" % (slash)
_files = (x for x in Path("dir2").iterdir() if x.is_file())

# Method 3: Find all files and all subfiles
dir3 = "%sfoo%sbar" % (slash)
_files = (x for x in Path('dir3').glob('**/*') if x.is_file())


# Step 2 - Add them to a list

files_list = []
for eachfiles in _files:
    files_basename = os.path.basename(eachfiles)
    files_list.append(files_basename)
print(files_list)
['file1.txt', 'file2.txt', .... ]

목록에 basenames 만을 원한다고 가정 합니다.

방법 1의 여러 파일 형식을 미리 정의 하려면이 post 을 참조하십시오 .


디렉토리를 매개 변수로 사용하여 findfiles ()를 실행하면 그 안에있는 모든 파일의 목록을 반환합니다.

import os
def findfiles(directory):
    objects = os.listdir(directory)  # find all objects in a dir

    files = []
    for i in objects:  # check if very object in the folder ...
        if os.path.isfile(os.path.join(directory, i)):  # ... is a file.
            files.append(i)  # if yes, append it.
    return files

import os
lst=os.listdir(path)

os.listdir은 path에 의해 주어진 디렉토리에있는 엔트리의 이름을 포함하는리스트를 반환합니다.


버전 3.4부터는 os.listdir() 보다 훨씬 더 효율적 인 iterator 가 내장되어 있습니다 :

pathlib : 버전 3.4에서 새로 추가되었습니다.

>>> import pathlib
>>> [p for p in pathlib.Path('.').iterdir() if p.is_file()]

PEP 428 에 따르면, pathlib 라이브러리의 목적은 파일 시스템 경로와 사용자가 수행하는 공통 작업을 처리하기위한 클래스의 간단한 계층 구조를 제공하는 것입니다.

os.scandir() : 버전 3.5에서 새로 추가되었습니다.

>>> import os
>>> [entry for entry in os.scandir('.') if entry.is_file()]

os.walk() 는 버전 3.5의 os.listdir() os.scandir() 대신 os.scandir() 사용하고 PEP 471 에 따라 속도가 2-20 배 증가했습니다.

아래 ShadowRanger의 의견을 읽어 보시기 바랍니다.


import os
os.listdir("somedirectory")

"somedirectory"에있는 모든 파일과 디렉토리 목록을 반환합니다.


제 2 부 1

솔루션 (계속)

다른 방법 :

  1. Python을 래퍼로만 사용하십시오.

    • 모든 것은 다른 기술을 사용하여 수행됩니다.
    • 이 기술은 Python 에서 호출됩니다.
    • 내가 아는 가장 유명한 맛은 내가 시스템 관리자 접근 방식 이라고 부르는 것이다 :

      • 사용 파이썬 실행하기 위해 (또는 그 문제에 대한 모든 프로그래밍 언어) 명령을 (자신의 출력을 구문 분석 - 일반적으로이 방법은 몇 가지 명령 출력 형식이 약간 사이에 다른 경우 때문에, 피해야하는 OS의 버전 / 맛, 구문 분석 코드가해야 EN 로고가 아닌 것은 말할 것도 없습니다. )
      • 일부는 이것을 깔끔한 해킹이라고 생각합니다.
      • 필자 는이 동작을 ( 이 경우 cmd) 에서 수행 하므로 Python 과 아무런 관련이 없으므로 불완전한 해결 방법 ( gainarie ) 과 같은 것으로 간주합니다 .
      • 필터링 ( grep/ findstr) 또는 출력 형식화는 양면에서 수행 될 수 있지만이를 주장하지는 않습니다. 또한, 나는 의도적으로 os.system대신 사용 했다 subprocess.Popen.
      (py35x64_test) E:\Work\Dev\\q003207219>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" -c "import os;os.system(\"dir /b root_dir\")"
      dir0
      dir1
      dir2
      dir3
      file0
      file1
      

제 2 부 끝 1


1. Home 의 게시물 (질문 / 답변) 한도가 30000 자 ( [SE.Meta] : 귀하의 한계 파악 : 질문 제목, 게시물, 이미지 및 사용 된 링크의 최대 길이는 얼마입니까? )라는 사실 때문에, 대답은 2 부분으로 나누어 져 있습니다. [SO] : 디렉토리의 모든 파일을 나열하려면 어떻게합니까? 를 읽으십시오 . (@ CristiFati의 대답 - "파트 1") .


import dircache
list = dircache.listdir(pathname)
i = 0
check = len(list[0])
temp = []
count = len(list)
while count != 0:
  if len(list[i]) != check:
     temp.append(list[i-1])
     check = len(list[i])
  else:
    i = i + 1
    count = count - 1

print temp

glob 모듈을 사용하는 것을 선호합니다. 패턴 일치 및 확장을 수행하기 때문입니다.

import glob
print(glob.glob("/home/adam/*.txt"))

쿼리 된 파일 목록을 반환합니다.

['/home/adam/file1.txt', '/home/adam/file2.txt', .... ]

def list_files(path):
    # returns a list of names (with extension, without full path) of all files 
    # in folder path
    files = []
    for name in os.listdir(path):
        if os.path.isfile(os.path.join(path, name)):
            files.append(name)
    return files 

find 의 파이썬 구현을 찾고 있다면 , 이것은 내가 자주 사용하는 방법입니다 :

from findtools.find_files import (find_files, Match)

# Recursively find all *.sh files in **/usr/bin**
sh_files_pattern = Match(filetype='f', name='*.sh')
found_files = find_files(path='/usr/bin', match=sh_files_pattern)

for found_file in found_files:
    print found_file

그래서 나는 PyPI에 만든 package 그것의와도있다 GitHub의 저장소 . 누군가이 코드에서 잠재적으로 유용하다고 생각하기를 바랍니다.


디렉토리 및 모든 하위 디렉토리에서 전체 파일 경로 얻기

import os

def get_filepaths(directory):
    """
    This function will generate the file names in a directory 
    tree by walking the tree either top-down or bottom-up. For each 
    directory in the tree rooted at directory top (including top itself), 
    it yields a 3-tuple (dirpath, dirnames, filenames).
    """
    file_paths = []  # List which will store all of the full filepaths.

    # Walk the tree.
    for root, directories, files in os.walk(directory):
        for filename in files:
            # Join the two strings in order to form the full filepath.
            filepath = os.path.join(root, filename)
            file_paths.append(filepath)  # Add it to the list.

    return file_paths  # Self-explanatory.

# Run the above function and store its results in a variable.   
full_file_paths = get_filepaths("/Users/johnny/Desktop/TEST")
  • 위의 함수에서 제공 한 경로에는 3 개의 파일이 포함되어 있는데 그 중 2 개는 루트 디렉토리에 있고 다른 하나는 "SUBFOLDER"라는 하위 폴더에 있습니다. 이제 다음과 같은 작업을 수행 할 수 있습니다.
  • 목록을 인쇄 할 print full_file_paths 를 인쇄하십시오.

    • ['/Users/johnny/Desktop/TEST/file1.txt', '/Users/johnny/Desktop/TEST/file2.txt', '/Users/johnny/Desktop/TEST/SUBFOLDER/file3.dat']

원한다면, 아래 코드와 같이 내용을 열고 읽을 수 있거나 확장명이 ".dat"인 파일에만 집중할 수 있습니다.

for f in full_file_paths:
  if f.endswith(".dat"):
    print f

/Users/johnny/Desktop/TEST/SUBFOLDER/file3.dat


import os
import os.path


def get_files(target_dir):
    item_list = os.listdir(target_dir)

    file_list = list()
    for item in item_list:
        item_dir = os.path.join(target_dir,item)
        if os.path.isdir(item_dir):
            file_list += get_files(item_dir)
        else:
            file_list.append(item_dir)
    return file_list

여기서 재귀 구조를 사용합니다.


발전기 사용

import os
def get_files(search_path):
     for (dirpath, _, filenames) in os.walk(search_path):
         for filename in filenames:
             yield os.path.join(dirpath, filename)
list_files = get_files('.')
for filename in list_files:
    print(filename)

import os 
os.listdir(path)

에있는 모든 파일 및 디렉토리 목록이 반환됩니다 path.

filenames = next(os.walk(path))[2]

그러면 하위 디렉토리가 아닌 파일 목록 만 반환됩니다.





directory