标签归档:subdirectory

从子文件夹导入模块

问题:从子文件夹导入模块

我想将子文件夹作为模块导入。因此,每个子文件夹都包含一个__init__.py。我的文件夹结构是这样的:

src\
  main.py
  dirFoo\
    __init__.py
    foofactory.py
    dirFoo1\
      __init__.py
      foo1.py
    dirFoo2\
      __init__.py
      foo2.py

在我的主脚本中,导入

from dirFoo.foofactory import FooFactory

在此工厂文件中,我包括以下子模块:

from dirFoo1.foo1 import Foo1
from dirFoo2.foo2 import Foo2

如果我叫我的foofactory我得到了错误,那说明python无法导入子模块foo1和foo2:

Traceback (most recent call last):
  File "/Users/tmp/src/main.py", line 1, in <module>
from dirFoo.foofactory import FooFactory
  File "/Users/tmp/src/dirFoo/foofactory.py", line 1, in    <module>
from dirFoo1.foo1 import Foo1
    ImportError: No module named dirFoo1.foo1

I want to import subfolders as modules. Therefore every subfolder contains a __init__.py. My folder structure is like this:

src\
  main.py
  dirFoo\
    __init__.py
    foofactory.py
    dirFoo1\
      __init__.py
      foo1.py
    dirFoo2\
      __init__.py
      foo2.py

In my main script I import

from dirFoo.foofactory import FooFactory

In this factory file I include the sub modules:

from dirFoo1.foo1 import Foo1
from dirFoo2.foo2 import Foo2

If I call my foofactory I get the error, that python can’t import the submodules foo1 and foo2:

Traceback (most recent call last):
  File "/Users/tmp/src/main.py", line 1, in <module>
from dirFoo.foofactory import FooFactory
  File "/Users/tmp/src/dirFoo/foofactory.py", line 1, in    <module>
from dirFoo1.foo1 import Foo1
    ImportError: No module named dirFoo1.foo1

回答 0

无需与您PYTHONPATHsys.path此处混淆。

为了在包中正确使用绝对导入,还应该包括“ root”包名,例如:

from dirFoo.dirFoo1.foo1 import Foo1
from dirFoo.dirFoo2.foo2 import Foo2

或者您可以使用相对导入

from .dirfoo1.foo1 import Foo1
from .dirfoo2.foo2 import Foo2

There’s no need to mess with your PYTHONPATH or sys.path here.

To properly use absolute imports in a package you should include the “root” packagename as well, e.g.:

from dirFoo.dirFoo1.foo1 import Foo1
from dirFoo.dirFoo2.foo2 import Foo2

Or you can use relative imports:

from .dirfoo1.foo1 import Foo1
from .dirfoo2.foo2 import Foo2

回答 1

只是在这里通知。(来自新蜜蜂keviv22)

永远不要为了自己的利益而用“-”或“ _”之类的符号命名文件夹或文件。如果这样做,您可能会遇到一些问题。就像我的一样,尽管导入命令正确无误,但您将无法成功导入所需的文件,这些文件在此类命名文件夹中可用。

无效的文件夹命名如下:

  • 通用类文件夹
  • Generic_Classes_Folder

上面的有效文件夹命名:

  • GenericClassesFolder或Genericclassesfolder或genericClassesFolder(或类似的词,单词之间没有任何空格或特殊符号)

我犯了什么错误:

考虑文件结构。

Parent
   . __init__.py
   . Setup
     .. __init__.py
     .. Generic-Class-Folder
        ... __init__.py
        ... targetClass.py
   . Check
     .. __init__.py
     .. testFile.py

我想做什么?

  • 从testFile.py,我想在Generic-Class-Folder文件中导入“ targetClass.py”文件,以在“ targetClass.py”文件中使用名为“ functionExecute”的函数

我做了什么命令?

  • 来自“ testFile.py”,写了命令, from Core.Generic-Class-Folder.targetClass import functionExecute
  • 有类似的错误 SyntaxError: invalid syntax

尝试了许多搜索并查看了许多stackoverflow问题,但无法确定出了什么问题。我多次交叉检查文件,使用__init__.py文件,插入环境路径,非常担心出了什么问题……

在很长很长一段时间后,我在和我的一个朋友交谈时想出了这一点。使用这样的命名约定我并不傻。我绝对不要使用空格或特殊符号为任何文件夹或文件定义名称。所以,这就是我想传达的。祝你有美好的一天!

(很抱歉在此发布大量文章……只是让我的挫败感….::)谢谢!)

Just to notify here. (from a newbee, keviv22)

Never and ever for the sake of your own good, name the folders or files with symbols like “-” or “_”. If you did so, you may face few issues. like mine, say, though your command for importing is correct, you wont be able to successfully import the desired files which are available inside such named folders.

Invalid Folder namings as follows:

  • Generic-Classes-Folder
  • Generic_Classes_Folder

valid Folder namings for above:

  • GenericClassesFolder or Genericclassesfolder or genericClassesFolder (or like this without any spaces or special symbols among the words)

What mistake I did:

consider the file structure.

Parent
   . __init__.py
   . Setup
     .. __init__.py
     .. Generic-Class-Folder
        ... __init__.py
        ... targetClass.py
   . Check
     .. __init__.py
     .. testFile.py

What I wanted to do?

  • from testFile.py, I wanted to import the ‘targetClass.py’ file inside the Generic-Class-Folder file to use the function named “functionExecute” in ‘targetClass.py’ file

What command I did?

  • from ‘testFile.py’, wrote command, from Core.Generic-Class-Folder.targetClass import functionExecute
  • Got errors like SyntaxError: invalid syntax

Tried many searches and viewed many stackoverflow questions and unable to decide what went wrong. I cross checked my files multiple times, i used __init__.py file, inserted environment path and hugely worried what went wrong……

And after a long long long time, i figured this out while talking with a friend of mine. I am little stupid to use such naming conventions. I should never use space or special symbols to define a name for any folder or file. So, this is what I wanted to convey. Have a good day!

(sorry for the huge post over this… just letting my frustrations go…. :) Thanks!)


回答 2

设置您的PYTHONPATH环境变量。例如这样的PYTHONPATH =。:..(对于* nix系列)。

您也可以手动将当前目录(在您的情况下为src)添加到pythonpath中:

import os
import sys
sys.path.insert(0, os.getcwd())

Set your PYTHONPATH environment variable. For example like this PYTHONPATH=.:.. (for *nix family).

Also you can manually add your current directory (src in your case) to pythonpath:

import os
import sys
sys.path.insert(0, os.getcwd())

回答 3

假设您的项目采用以下结构:

+---MyPythonProject
|   +---.gitignore
|   +---run.py
|   |   +---subscripts
|   |   |   +---script_one.py
|   |   |   +---script_two.py

run.py,您可以通过以下方式导入脚本一和二:

from subscripts import script_one as One
from subscripts import script_two as Two

现在,仍然在内run.py,您可以使用以下命令调用其方法:

One.method_from_one(param)
Two.method_from_two(other_param)

Say your project is structured this way:

+---MyPythonProject
|   +---.gitignore
|   +---run.py
|   |   +---subscripts
|   |   |   +---script_one.py
|   |   |   +---script_two.py

Inside run.py, you can import scripts one and two by:

from subscripts import script_one as One
from subscripts import script_two as Two

Now, still inside run.py, you’ll be able to call their methods with:

One.method_from_one(param)
Two.method_from_two(other_param)

回答 4

只需创建一个空的____init____.py文件,并将其添加到root以及您拥有其他python模块的python应用程序的所有子目录/文件夹中即可。

Just create an empty __init__.py file and add it in root as well as all the sub directory/folder of your python application where you have other python modules. See https://docs.python.org/3/tutorial/modules.html#packages


回答 5

即使子文件夹中存在init .py且在导入后添加“ as” 时仍存在问题

from folder.file import Class as Class
import folder.file as functions

Had problems even when init.py existed in subfolder and all that was missing was adding ‘as’ after import

from folder.file import Class as Class
import folder.file as functions

Python中的目录树列表

问题:Python中的目录树列表

如何获取Python给定目录中所有文件(和目录)的列表?

How do I get a list of all files (and directories) in a given directory in Python?


回答 0

这是遍历目录树中每个文件和目录的一种方式:

import os

for dirname, dirnames, filenames in os.walk('.'):
    # print path to all subdirectories first.
    for subdirname in dirnames:
        print(os.path.join(dirname, subdirname))

    # print path to all filenames.
    for filename in filenames:
        print(os.path.join(dirname, filename))

    # Advanced usage:
    # editing the 'dirnames' list will stop os.walk() from recursing into there.
    if '.git' in dirnames:
        # don't go into any .git directories.
        dirnames.remove('.git')

This is a way to traverse every file and directory in a directory tree:

import os

for dirname, dirnames, filenames in os.walk('.'):
    # print path to all subdirectories first.
    for subdirname in dirnames:
        print(os.path.join(dirname, subdirname))

    # print path to all filenames.
    for filename in filenames:
        print(os.path.join(dirname, filename))

    # Advanced usage:
    # editing the 'dirnames' list will stop os.walk() from recursing into there.
    if '.git' in dirnames:
        # don't go into any .git directories.
        dirnames.remove('.git')

回答 1

您可以使用

os.listdir(path)

作为参考和更多的os函数,请看这里:

You can use

os.listdir(path)

For reference and more os functions look here:


回答 2

这是我经常使用的辅助函数:

import os

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

Here’s a helper function I use quite often:

import os

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

回答 3

import os

for filename in os.listdir("C:\\temp"):
    print  filename
import os

for filename in os.listdir("C:\\temp"):
    print  filename

回答 4

如果您需要遍历功能,那么还可以使用一个模块。例如:

import glob
glob.glob('./[0-9].*')

将返回类似:

['./1.gif', './2.txt']

请参阅此处的文档。

If you need globbing abilities, there’s a module for that as well. For example:

import glob
glob.glob('./[0-9].*')

will return something like:

['./1.gif', './2.txt']

See the documentation here.


回答 5

尝试这个:

import os
for top, dirs, files in os.walk('./'):
    for nm in files:       
        print os.path.join(top, nm)

Try this:

import os
for top, dirs, files in os.walk('./'):
    for nm in files:       
        print os.path.join(top, nm)

回答 6

对于当前工作目录中的文件,但未指定路径

Python 2.7:

import os
os.listdir(os.getcwd())

Python 3.x:

import os
os.listdir()

感谢Stam Kaly对python 3.x的评论

For files in current working directory without specifying a path

Python 2.7:

import os
os.listdir(os.getcwd())

Python 3.x:

import os
os.listdir()

Thanks to Stam Kaly for comment on python 3.x


回答 7

递归实现

import os

def scan_dir(dir):
    for name in os.listdir(dir):
        path = os.path.join(dir, name)
        if os.path.isfile(path):
            print path
        else:
            scan_dir(path)

A recursive implementation

import os

def scan_dir(dir):
    for name in os.listdir(dir):
        path = os.path.join(dir, name)
        if os.path.isfile(path):
            print path
        else:
            scan_dir(path)

回答 8

我写了一个很长的版本,其中包含了我可能需要的所有选项:http : //sam.nipl.net/code/python/find.py

我想它也适合这里:

#!/usr/bin/env python

import os
import sys

def ls(dir, hidden=False, relative=True):
    nodes = []
    for nm in os.listdir(dir):
        if not hidden and nm.startswith('.'):
            continue
        if not relative:
            nm = os.path.join(dir, nm)
        nodes.append(nm)
    nodes.sort()
    return nodes

def find(root, files=True, dirs=False, hidden=False, relative=True, topdown=True):
    root = os.path.join(root, '')  # add slash if not there
    for parent, ldirs, lfiles in os.walk(root, topdown=topdown):
        if relative:
            parent = parent[len(root):]
        if dirs and parent:
            yield os.path.join(parent, '')
        if not hidden:
            lfiles   = [nm for nm in lfiles if not nm.startswith('.')]
            ldirs[:] = [nm for nm in ldirs  if not nm.startswith('.')]  # in place
        if files:
            lfiles.sort()
            for nm in lfiles:
                nm = os.path.join(parent, nm)
                yield nm

def test(root):
    print "* directory listing, with hidden files:"
    print ls(root, hidden=True)
    print
    print "* recursive listing, with dirs, but no hidden files:"
    for f in find(root, dirs=True):
        print f
    print

if __name__ == "__main__":
    test(*sys.argv[1:])

I wrote a long version, with all the options I might need: http://sam.nipl.net/code/python/find.py

I guess it will fit here too:

#!/usr/bin/env python

import os
import sys

def ls(dir, hidden=False, relative=True):
    nodes = []
    for nm in os.listdir(dir):
        if not hidden and nm.startswith('.'):
            continue
        if not relative:
            nm = os.path.join(dir, nm)
        nodes.append(nm)
    nodes.sort()
    return nodes

def find(root, files=True, dirs=False, hidden=False, relative=True, topdown=True):
    root = os.path.join(root, '')  # add slash if not there
    for parent, ldirs, lfiles in os.walk(root, topdown=topdown):
        if relative:
            parent = parent[len(root):]
        if dirs and parent:
            yield os.path.join(parent, '')
        if not hidden:
            lfiles   = [nm for nm in lfiles if not nm.startswith('.')]
            ldirs[:] = [nm for nm in ldirs  if not nm.startswith('.')]  # in place
        if files:
            lfiles.sort()
            for nm in lfiles:
                nm = os.path.join(parent, nm)
                yield nm

def test(root):
    print "* directory listing, with hidden files:"
    print ls(root, hidden=True)
    print
    print "* recursive listing, with dirs, but no hidden files:"
    for f in find(root, dirs=True):
        print f
    print

if __name__ == "__main__":
    test(*sys.argv[1:])

回答 9

这是另一种选择。

os.scandir(path='.')

它返回os.DirEntry对象的迭代器,该对象与path所给目录中的条目(以及文件属性信息)相对应。

例:

with os.scandir(path) as it:
    for entry in it:
        if not entry.name.startswith('.'):
            print(entry.name)

使用scandir()而不是listdir()可以显着提高还需要文件类型或文件属性信息的代码的性能,因为如果操作系统在扫描目录时提供了os.DirEntry对象,则该信息会公开。所有的os.DirEntry方法都可以执行系统调用,但是is_dir()和is_file()通常只需要系统调用即可进行符号链接。os.DirEntry.stat()在Unix上始终需要系统调用,而在Windows上只需要一个系统调用即可。

Python文档

Here is another option.

os.scandir(path='.')

It returns an iterator of os.DirEntry objects corresponding to the entries (along with file attribute information) in the directory given by path.

Example:

with os.scandir(path) as it:
    for entry in it:
        if not entry.name.startswith('.'):
            print(entry.name)

Using scandir() instead of listdir() can significantly increase the performance of code that also needs file type or file attribute information, because os.DirEntry objects expose this information if the operating system provides it when scanning a directory. All os.DirEntry methods may perform a system call, but is_dir() and is_file() usually only require a system call for symbolic links; os.DirEntry.stat() always requires a system call on Unix but only requires one for symbolic links on Windows.

Python Docs


回答 10

虽然os.listdir()可以很好地生成文件名和目录名列表,但是一旦拥有了这些文件名,就经常想做更多的事情-在Python3中,pathlib使其他琐事变得简单。让我们看一下,看看您是否像我一样喜欢它。

要列出目录内容,请构造一个Path对象并获取迭代器:

In [16]: Path('/etc').iterdir()
Out[16]: <generator object Path.iterdir at 0x110853fc0>

如果我们只想要事物名称列表:

In [17]: [x.name for x in Path('/etc').iterdir()]
Out[17]:
['emond.d',
 'ntp-restrict.conf',
 'periodic',

如果您只想要Dirs:

In [18]: [x.name for x in Path('/etc').iterdir() if x.is_dir()]
Out[18]:
['emond.d',
 'periodic',
 'mach_init.d',

如果您想要该树中所有conf文件的名称:

In [20]: [x.name for x in Path('/etc').glob('**/*.conf')]
Out[20]:
['ntp-restrict.conf',
 'dnsextd.conf',
 'syslog.conf',

如果要在树中的conf文件列表> = 1K中:

In [23]: [x.name for x in Path('/etc').glob('**/*.conf') if x.stat().st_size > 1024]
Out[23]:
['dnsextd.conf',
 'pf.conf',
 'autofs.conf',

解决相对路径变得容易:

In [32]: Path('../Operational Metrics.md').resolve()
Out[32]: PosixPath('/Users/starver/code/xxxx/Operational Metrics.md')

使用路径导航非常清晰(尽管出乎意料):

In [10]: p = Path('.')

In [11]: core = p / 'web' / 'core'

In [13]: [x for x in core.iterdir() if x.is_file()]
Out[13]:
[PosixPath('web/core/metrics.py'),
 PosixPath('web/core/services.py'),
 PosixPath('web/core/querysets.py'),

While os.listdir() is fine for generating a list of file and dir names, frequently you want to do more once you have those names – and in Python3, pathlib makes those other chores simple. Let’s take a look and see if you like it as much as I do.

To list dir contents, construct a Path object and grab the iterator:

In [16]: Path('/etc').iterdir()
Out[16]: <generator object Path.iterdir at 0x110853fc0>

If we want just a list of names of things:

In [17]: [x.name for x in Path('/etc').iterdir()]
Out[17]:
['emond.d',
 'ntp-restrict.conf',
 'periodic',

If you want just the dirs:

In [18]: [x.name for x in Path('/etc').iterdir() if x.is_dir()]
Out[18]:
['emond.d',
 'periodic',
 'mach_init.d',

If you want the names of all conf files in that tree:

In [20]: [x.name for x in Path('/etc').glob('**/*.conf')]
Out[20]:
['ntp-restrict.conf',
 'dnsextd.conf',
 'syslog.conf',

If you want a list of conf files in the tree >= 1K:

In [23]: [x.name for x in Path('/etc').glob('**/*.conf') if x.stat().st_size > 1024]
Out[23]:
['dnsextd.conf',
 'pf.conf',
 'autofs.conf',

Resolving relative paths become easy:

In [32]: Path('../Operational Metrics.md').resolve()
Out[32]: PosixPath('/Users/starver/code/xxxx/Operational Metrics.md')

Navigating with a Path is pretty clear (although unexpected):

In [10]: p = Path('.')

In [11]: core = p / 'web' / 'core'

In [13]: [x for x in core.iterdir() if x.is_file()]
Out[13]:
[PosixPath('web/core/metrics.py'),
 PosixPath('web/core/services.py'),
 PosixPath('web/core/querysets.py'),

回答 11

一个很好的衬垫,可以递归地仅列出文件。我在setup.py package_data指令中使用了此命令:

import os

[os.path.join(x[0],y) for x in os.walk('<some_directory>') for y in x[2]]

我知道这不是问题的答案,但可能会派上用场

A nice one liner to list only the files recursively. I used this in my setup.py package_data directive:

import os

[os.path.join(x[0],y) for x in os.walk('<some_directory>') for y in x[2]]

I know it’s not the answer to the question, but may come in handy


回答 12

对于Python 2

#!/bin/python2

import os

def scan_dir(path):
    print map(os.path.abspath, os.listdir(pwd))

对于Python 3

对于过滤器和地图,您需要使用list()包装它们

#!/bin/python3

import os

def scan_dir(path):
    print(list(map(os.path.abspath, os.listdir(pwd))))

现在的建议是,用生成器表达式或列表推导替换map和filter的用法:

#!/bin/python

import os

def scan_dir(path):
    print([os.path.abspath(f) for f in os.listdir(path)])

For Python 2

#!/bin/python2

import os

def scan_dir(path):
    print map(os.path.abspath, os.listdir(pwd))

For Python 3

For filter and map, you need wrap them with list()

#!/bin/python3

import os

def scan_dir(path):
    print(list(map(os.path.abspath, os.listdir(pwd))))

The recommendation now is that you replace your usage of map and filter with generators expressions or list comprehensions:

#!/bin/python

import os

def scan_dir(path):
    print([os.path.abspath(f) for f in os.listdir(path)])

回答 13

这是一行Pythonic版本:

import os
dir = 'given_directory_name'
filenames = [os.path.join(os.path.dirname(os.path.abspath(__file__)),dir,i) for i in os.listdir(dir)]

此代码列出了给定目录名称中所有文件和目录的完整路径。

Here is a one line Pythonic version:

import os
dir = 'given_directory_name'
filenames = [os.path.join(os.path.dirname(os.path.abspath(__file__)),dir,i) for i in os.listdir(dir)]

This code lists the full path of all files and directories in the given directory name.


回答 14

我知道这是一个老问题。如果您使用的是liunx机器,这是我遇到的一种巧妙方法。

import subprocess
print(subprocess.check_output(["ls", "/"]).decode("utf8"))

I know this is an old question. This is a neat way I came across if you are on a liunx machine.

import subprocess
print(subprocess.check_output(["ls", "/"]).decode("utf8"))

回答 15

#import modules
import os

_CURRENT_DIR = '.'


def rec_tree_traverse(curr_dir, indent):
    "recurcive function to traverse the directory"
    #print "[traverse_tree]"

    try :
        dfList = [os.path.join(curr_dir, f_or_d) for f_or_d in os.listdir(curr_dir)]
    except:
        print "wrong path name/directory name"
        return

    for file_or_dir in dfList:

        if os.path.isdir(file_or_dir):
            #print "dir  : ",
            print indent, file_or_dir,"\\"
            rec_tree_traverse(file_or_dir, indent*2)

        if os.path.isfile(file_or_dir):
            #print "file : ",
            print indent, file_or_dir

    #end if for loop
#end of traverse_tree()

def main():

    base_dir = _CURRENT_DIR

    rec_tree_traverse(base_dir," ")

    raw_input("enter any key to exit....")
#end of main()


if __name__ == '__main__':
    main()
#import modules
import os

_CURRENT_DIR = '.'


def rec_tree_traverse(curr_dir, indent):
    "recurcive function to traverse the directory"
    #print "[traverse_tree]"

    try :
        dfList = [os.path.join(curr_dir, f_or_d) for f_or_d in os.listdir(curr_dir)]
    except:
        print "wrong path name/directory name"
        return

    for file_or_dir in dfList:

        if os.path.isdir(file_or_dir):
            #print "dir  : ",
            print indent, file_or_dir,"\\"
            rec_tree_traverse(file_or_dir, indent*2)

        if os.path.isfile(file_or_dir):
            #print "file : ",
            print indent, file_or_dir

    #end if for loop
#end of traverse_tree()

def main():

    base_dir = _CURRENT_DIR

    rec_tree_traverse(base_dir," ")

    raw_input("enter any key to exit....")
#end of main()


if __name__ == '__main__':
    main()

回答 16

仅供参考,添加扩展名或扩展名文件过滤器os

path = '.'
for dirname, dirnames, filenames in os.walk(path):
    # print path to all filenames with extension py.
    for filename in filenames:
        fname_path = os.path.join(dirname, filename)
        fext = os.path.splitext(fname_path)[1]
        if fext == '.py':
            print fname_path
        else:
            continue

FYI Add a filter of extension or ext file import os

path = '.'
for dirname, dirnames, filenames in os.walk(path):
    # print path to all filenames with extension py.
    for filename in filenames:
        fname_path = os.path.join(dirname, filename)
        fext = os.path.splitext(fname_path)[1]
        if fext == '.py':
            print fname_path
        else:
            continue

回答 17

如果知道的话,我会把它扔进去。通配符搜索的简单而肮脏的方法。

import re
import os

[a for a in os.listdir(".") if re.search("^.*\.py$",a)]

If figured I’d throw this in. Simple and dirty way to do wildcard searches.

import re
import os

[a for a in os.listdir(".") if re.search("^.*\.py$",a)]

回答 18

下面的代码将列出目录和目录中的文件

def print_directory_contents(sPath):
        import os                                       
        for sChild in os.listdir(sPath):                
            sChildPath = os.path.join(sPath,sChild)
            if os.path.isdir(sChildPath):
                print_directory_contents(sChildPath)
            else:
                print(sChildPath)

Below code will list directories and the files within the dir

def print_directory_contents(sPath):
        import os                                       
        for sChild in os.listdir(sPath):                
            sChildPath = os.path.join(sPath,sChild)
            if os.path.isdir(sChildPath):
                print_directory_contents(sChildPath)
            else:
                print(sChildPath)

回答 19

和我一起工作的人是上述萨利赫回答的一种修改版本。

代码如下:

“ dir =’given_directory_name’文件名= [os.listdir(dir)中用于i的os.path.abspath(os.path.join(dir,i))]”

The one worked with me is kind of a modified version from Saleh answer above.

The code is as follows:

“dir = ‘given_directory_name’ filenames = [os.path.abspath(os.path.join(dir,i)) for i in os.listdir(dir)]”


获取当前目录中所有子目录的列表

问题:获取当前目录中所有子目录的列表

有没有办法在Python中返回当前目录中所有子目录的列表?

我知道您可以使用文件来执行此操作,但是我需要获取目录列表。

Is there a way to return a list of all the subdirectories in the current directory in Python?

I know you can do this with files, but I need to get the list of directories instead.


回答 0

您是指直接子目录,还是树下的每个目录?

无论哪种方式,您都可以使用os.walk以下方法:

os.walk(directory)

将为每个子目录生成一个元组。该三元组中的第一个条目是目录名称,因此

[x[0] for x in os.walk(directory)]

应该递归地给你所有的子目录。

请注意,该元组中的第二个条目是该条目的子目录列表的第一个位置,因此您可以改用它,但是不太可能为您节省很多。

但是,您可以使用它来为您提供直接的子目录:

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

或者使用os.listdir和查看已经发布的其他解决方案os.path.isdir,包括“ 如何在Python中获取所有直接子目录 ”中的解决方案。

Do you mean immediate subdirectories, or every directory right down the tree?

Either way, you could use os.walk to do this:

os.walk(directory)

will yield a tuple for each subdirectory. Ths first entry in the 3-tuple is a directory name, so

[x[0] for x in os.walk(directory)]

should give you all of the subdirectories, recursively.

Note that the second entry in the tuple is the list of child directories of the entry in the first position, so you could use this instead, but it’s not likely to save you much.

However, you could use it just to give you the immediate child directories:

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

Or see the other solutions already posted, using os.listdir and os.path.isdir, including those at “How to get all of the immediate subdirectories in Python“.


回答 1

import os

d = '.'
[os.path.join(d, o) for o in os.listdir(d) 
                    if os.path.isdir(os.path.join(d,o))]
import os

d = '.'
[os.path.join(d, o) for o in os.listdir(d) 
                    if os.path.isdir(os.path.join(d,o))]

回答 2

你可以用 glob.glob

from glob import glob
glob("/path/to/directory/*/")

别忘了/之后的尾随*

You could just use glob.glob

from glob import glob
glob("/path/to/directory/*/")

Don’t forget the trailing / after the *.


回答 3

比上面的要好得多,因为您不需要几个os.path.join(),并且可以直接获取完整路径(如果需要),因此可以在Python 3.5及更高版本中执行此操作。

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

这将提供到子目录的完整路径。如果只希望使用子目录的名称,f.name而不是f.path

https://docs.python.org/3/library/os.html#os.scandir


OT:如果您需要递归所有子文件夹和/或所有文件,请看一下此功能,它比os.walk&快,glob并且将返回所有子文件夹以及这些(子)子文件夹中的所有文件的列表:https://stackoverflow.com/a/59803793/2441026

如果您只需要递归所有子文件夹

def fast_scandir(dirname):
    subfolders= [f.path for f in os.scandir(dirname) if f.is_dir()]
    for dirname in list(subfolders):
        subfolders.extend(fast_scandir(dirname))
    return subfolders

返回所有子文件夹及其完整路径的列表。这又比os.walk和快得多glob


所有功能分析

tl; dr:
-如果要获取文件夹使用的所有直接子目录os.scandir
-如果要获取所有子目录,甚至嵌套的子目录,请使用os.walk或-稍微快一点- fast_scandir上面的函数。
-从来不使用os.walk只顶级子目录,因为它可以是数百倍慢于(!) os.scandir

  • 如果您运行下面的代码,请确保运行一次,以便您的操作系统可以访问该文件夹,丢弃结果并运行测试,否则结果将被弄乱。
  • 您可能想混淆函数调用,但是我对其进行了测试,但这并不重要。
  • 所有示例都将提供文件夹的完整路径。pathlib示例作为(Windows)Path对象。
  • 的第一个元素os.walk将是基本文件夹。因此,您将不会仅获得子目录。您可以使用fu.pop(0)将其删除。
  • 所有结果都不会使用自然排序。这意味着将对结果进行如下排序:1、10、2。要进行自然排序(1、2、10),请查看https://stackoverflow.com/a/48030307/2441026


结果

os.scandir      took   1 ms. Found dirs: 439
os.walk         took 463 ms. Found dirs: 441 -> it found the nested one + base folder.
glob.glob       took  20 ms. Found dirs: 439
pathlib.iterdir took  18 ms. Found dirs: 439
os.listdir      took  18 ms. Found dirs: 439

已在W7x64,Python 3.8.1中测试。

# -*- coding: utf-8 -*-
# Python 3


import time
import os
from glob import glob
from pathlib import Path


directory = r"<insert_folder>"
RUNS = 1


def run_os_walk():
    a = time.time_ns()
    for i in range(RUNS):
        fu = [x[0] for x in os.walk(directory)]
    print(f"os.walk\t\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")


def run_glob():
    a = time.time_ns()
    for i in range(RUNS):
        fu = glob(directory + "/*/")
    print(f"glob.glob\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")


def run_pathlib_iterdir():
    a = time.time_ns()
    for i in range(RUNS):
        dirname = Path(directory)
        fu = [f for f in dirname.iterdir() if f.is_dir()]
    print(f"pathlib.iterdir\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")


def run_os_listdir():
    a = time.time_ns()
    for i in range(RUNS):
        dirname = Path(directory)
        fu = [os.path.join(directory, o) for o in os.listdir(directory) if os.path.isdir(os.path.join(directory, o))]
    print(f"os.listdir\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")


def run_os_scandir():
    a = time.time_ns()
    for i in range(RUNS):
        fu = [f.path for f in os.scandir(directory) if f.is_dir()]
    print(f"os.scandir\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms.\tFound dirs: {len(fu)}")


if __name__ == '__main__':
    run_os_scandir()
    run_os_walk()
    run_glob()
    run_pathlib_iterdir()
    run_os_listdir()

Much nicer than the above, because you don’t need several os.path.join() and you will get the full path directly (if you wish), you can do this in Python 3.5 and above.

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

This will give the complete path to the subdirectory. If you only want the name of the subdirectory use f.name instead of f.path

https://docs.python.org/3/library/os.html#os.scandir


Slightly OT: In case you need all subfolder recursively and/or all files recursively, have a look at this function, that is faster than os.walk & glob and will return a list of all subfolders as well as all files inside those (sub-)subfolders: https://stackoverflow.com/a/59803793/2441026

In case you want only all subfolders recursively:

def fast_scandir(dirname):
    subfolders= [f.path for f in os.scandir(dirname) if f.is_dir()]
    for dirname in list(subfolders):
        subfolders.extend(fast_scandir(dirname))
    return subfolders

Returns a list of all subfolders with their full paths. This again is faster than os.walk and a lot faster than glob.


An analysis of all functions

tl;dr:
– If you want to get all immediate subdirectories for a folder use os.scandir.
– If you want to get all subdirectories, even nested ones, use os.walk or – slightly faster – the fast_scandir function above.
– Never use os.walk for only top-level subdirectories, as it can be hundreds(!) of times slower than os.scandir.

  • If you run the code below, make sure to run it once so that your OS will have accessed the folder, discard the results and run the test, otherwise results will be screwed.
  • You might want to mix up the function calls, but I tested it, and it did not really matter.
  • All examples will give the full path to the folder. The pathlib example as a (Windows)Path object.
  • The first element of os.walk will be the base folder. So you will not get only subdirectories. You can use fu.pop(0) to remove it.
  • None of the results will use natural sorting. This means results will be sorted like this: 1, 10, 2. To get natural sorting (1, 2, 10), please have a look at https://stackoverflow.com/a/48030307/2441026


Results:

os.scandir      took   1 ms. Found dirs: 439
os.walk         took 463 ms. Found dirs: 441 -> it found the nested one + base folder.
glob.glob       took  20 ms. Found dirs: 439
pathlib.iterdir took  18 ms. Found dirs: 439
os.listdir      took  18 ms. Found dirs: 439

Tested with W7x64, Python 3.8.1.

# -*- coding: utf-8 -*-
# Python 3


import time
import os
from glob import glob
from pathlib import Path


directory = r"<insert_folder>"
RUNS = 1


def run_os_walk():
    a = time.time_ns()
    for i in range(RUNS):
        fu = [x[0] for x in os.walk(directory)]
    print(f"os.walk\t\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")


def run_glob():
    a = time.time_ns()
    for i in range(RUNS):
        fu = glob(directory + "/*/")
    print(f"glob.glob\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")


def run_pathlib_iterdir():
    a = time.time_ns()
    for i in range(RUNS):
        dirname = Path(directory)
        fu = [f for f in dirname.iterdir() if f.is_dir()]
    print(f"pathlib.iterdir\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")


def run_os_listdir():
    a = time.time_ns()
    for i in range(RUNS):
        dirname = Path(directory)
        fu = [os.path.join(directory, o) for o in os.listdir(directory) if os.path.isdir(os.path.join(directory, o))]
    print(f"os.listdir\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms. Found dirs: {len(fu)}")


def run_os_scandir():
    a = time.time_ns()
    for i in range(RUNS):
        fu = [f.path for f in os.scandir(directory) if f.is_dir()]
    print(f"os.scandir\t\ttook {(time.time_ns() - a) / 1000 / 1000 / RUNS:.0f} ms.\tFound dirs: {len(fu)}")


if __name__ == '__main__':
    run_os_scandir()
    run_os_walk()
    run_glob()
    run_pathlib_iterdir()
    run_os_listdir()

回答 4

如果您需要一个可在子目录中找到所有子目录的递归解决方案,请按照之前的建议使用walk。

如果仅需要当前目录的子目录,请os.listdiros.path.isdir

If you need a recursive solution that will find all the subdirectories in the subdirectories, use walk as proposed before.

If you only need the current directory’s child directories, combine os.listdir with os.path.isdir


回答 5

我更喜欢使用过滤器(https://docs.python.org/2/library/functions.html#filter),但这只是一个问题。

d='.'
filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d))

I prefer using filter (https://docs.python.org/2/library/functions.html#filter), but this is just a matter of taste.

d='.'
filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d))

回答 6

使用python-os-walk实现了这一点。(http://www.pythonforbeginners.com/code-snippets-source-code/python-os-walk/

import os

print("root prints out directories only from what you specified")
print("dirs prints out sub-directories from root")
print("files prints out all files from root and directories")
print("*" * 20)

for root, dirs, files in os.walk("/var/log"):
    print(root)
    print(dirs)
    print(files)

Implemented this using python-os-walk. (http://www.pythonforbeginners.com/code-snippets-source-code/python-os-walk/)

import os

print("root prints out directories only from what you specified")
print("dirs prints out sub-directories from root")
print("files prints out all files from root and directories")
print("*" * 20)

for root, dirs, files in os.walk("/var/log"):
    print(root)
    print(dirs)
    print(files)

回答 7

您可以使用os.listdir(path)获取Python 2.7中的子目录(和文件)列表

import os
os.listdir(path)  # list of subdirectories and files

You can get the list of subdirectories (and files) in Python 2.7 using os.listdir(path)

import os
os.listdir(path)  # list of subdirectories and files

回答 8

仅列出目录

print("\nWe are listing out only the directories in current directory -")
directories_in_curdir = filter(os.path.isdir, os.listdir(os.curdir))
print(directories_in_curdir)

仅列出当前目录中的文件

files = filter(os.path.isfile, os.listdir(os.curdir))
print("\nThe following are the list of all files in the current directory -")
print(files)

Listing Out only directories

print("\nWe are listing out only the directories in current directory -")
directories_in_curdir = filter(os.path.isdir, os.listdir(os.curdir))
print(directories_in_curdir)

Listing Out only files in current directory

files = filter(os.path.isfile, os.listdir(os.curdir))
print("\nThe following are the list of all files in the current directory -")
print(files)

回答 9

蟒3.4引入pathlib模块到标准库,它提供了一个面向对象的方法来处理的文件系统的路径:

from pathlib import Path

p = Path('./')

# List comprehension
[f for f in p.iterdir() if f.is_dir()]

# The trailing slash to glob indicated directories
# This will also include the current directory '.'
list(p.glob('**/'))

也可以通过PyPi上的pathlib2模块在 Python 2.7 上使用Pathlib。

Python 3.4 introduced the pathlib module into the standard library, which provides an object oriented approach to handle filesystem paths:

from pathlib import Path

p = Path('./')

# List comprehension
[f for f in p.iterdir() if f.is_dir()]

# The trailing slash to glob indicated directories
# This will also include the current directory '.'
list(p.glob('**/'))

Pathlib is also available on Python 2.7 via the pathlib2 module on PyPi.


回答 10

由于我使用Python 3.4和Windows UNC路径偶然发现了此问题,因此以下是此环境的变体:

from pathlib import WindowsPath

def SubDirPath (d):
    return [f for f in d.iterdir() if f.is_dir()]

subdirs = SubDirPath(WindowsPath(r'\\file01.acme.local\home$'))
print(subdirs)

Pathlib是Python 3.4中的新增功能,它使在不同操作系统下使用路径变得更加容易:https ://docs.python.org/3.4/library/pathlib.html

Since I stumbled upon this problem using Python 3.4 and Windows UNC paths, here’s a variant for this environment:

from pathlib import WindowsPath

def SubDirPath (d):
    return [f for f in d.iterdir() if f.is_dir()]

subdirs = SubDirPath(WindowsPath(r'\\file01.acme.local\home$'))
print(subdirs)

Pathlib is new in Python 3.4 and makes working with paths under different OSes much easier: https://docs.python.org/3.4/library/pathlib.html


回答 11

尽管很久以前就回答了这个问题。我想建议使用该pathlib模块,因为这是在Windows和Unix OS上工作的可靠方法。

因此,要获取特定目录(包括子目录)中的所有路径:

from pathlib import Path
paths = list(Path('myhomefolder', 'folder').glob('**/*.txt'))

# all sorts of operations
file = paths[0]
file.name
file.stem
file.parent
file.suffix

等等

Although this question is answered a long time ago. I want to recommend to use the pathlib module since this is a robust way to work on Windows and Unix OS.

So to get all paths in a specific directory including subdirectories:

from pathlib import Path
paths = list(Path('myhomefolder', 'folder').glob('**/*.txt'))

# all sorts of operations
file = paths[0]
file.name
file.stem
file.parent
file.suffix

etc.


回答 12

谢谢提醒伙计。我遇到了一个以dirs返回的软链接(无限递归)的问题。软链接?我们不希望没有臭味的软链接!所以…

这仅显示目录,而不显示软链接:

>>> import os
>>> inf = os.walk('.')
>>> [x[0] for x in inf]
['.', './iamadir']

Thanks for the tips, guys. I ran into an issue with softlinks (infinite recursion) being returned as dirs. Softlinks? We don’t want no stinkin’ soft links! So…

This rendered just the dirs, not softlinks:

>>> import os
>>> inf = os.walk('.')
>>> [x[0] for x in inf]
['.', './iamadir']

回答 13

复制粘贴友好ipython

import os
d='.'
folders = list(filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d)))

来自的输出print(folders)

['folderA', 'folderB']

Copy paste friendly in ipython:

import os
d='.'
folders = list(filter(lambda x: os.path.isdir(os.path.join(d, x)), os.listdir(d)))

Output from print(folders):

['folderA', 'folderB']

回答 14

这就是我的方法。

    import os
    for x in os.listdir(os.getcwd()):
        if os.path.isdir(x):
            print(x)

This is how I do it.

    import os
    for x in os.listdir(os.getcwd()):
        if os.path.isdir(x):
            print(x)

回答 15

这是基于@Blair Conrad的示例的几个简单函数-

import os

def get_subdirs(dir):
    "Get a list of immediate subdirectories"
    return next(os.walk(dir))[1]

def get_subfiles(dir):
    "Get a list of immediate subfiles"
    return next(os.walk(dir))[2]

Here are a couple of simple functions based on @Blair Conrad’s example –

import os

def get_subdirs(dir):
    "Get a list of immediate subdirectories"
    return next(os.walk(dir))[1]

def get_subfiles(dir):
    "Get a list of immediate subfiles"
    return next(os.walk(dir))[2]

回答 16

在Eli Bendersky解决方案的基础上,使用以下示例:

import os
test_directory = <your_directory>
for child in os.listdir(test_directory):
    test_path = os.path.join(test_directory, child)
    if os.path.isdir(test_path):
        print test_path
        # Do stuff to the directory "test_path"

<your_directory>您要遍历的目录的路径在哪里。

Building upon Eli Bendersky’s solution, use the following example:

import os
test_directory = <your_directory>
for child in os.listdir(test_directory):
    test_path = os.path.join(test_directory, child)
    if os.path.isdir(test_path):
        print test_path
        # Do stuff to the directory "test_path"

where <your_directory> is the path to the directory you want to traverse.


回答 17

有了完整路径和占路感...\\..\\..\\subfolder,等:

import os, pprint
pprint.pprint([os.path.join(os.path.abspath(path), x[0]) \
    for x in os.walk(os.path.abspath(path))])

With full path and accounting for path being ., .., \\, ..\\..\\subfolder, etc:

import os, pprint
pprint.pprint([os.path.join(os.path.abspath(path), x[0]) \
    for x in os.walk(os.path.abspath(path))])

回答 18

这个答案似乎还不存在。

directories = [ x for x in os.listdir('.') if os.path.isdir(x) ]

This answer didn’t seem to exist already.

directories = [ x for x in os.listdir('.') if os.path.isdir(x) ]

回答 19

我最近有一个类似的问题,我发现python 3.6(作为用户havlock添加)的最佳答案是使用os.scandir。由于似乎没有使用它的解决方案,因此我将添加自己的解决方案。首先,一种非递归解决方案,仅列出直接位于根目录下的子目录。

def get_dirlist(rootdir):

    dirlist = []

    with os.scandir(rootdir) as rit:
        for entry in rit:
            if not entry.name.startswith('.') and entry.is_dir():
                dirlist.append(entry.path)

    dirlist.sort() # Optional, in case you want sorted directory names
    return dirlist

递归版本如下所示:

def get_dirlist(rootdir):

    dirlist = []

    with os.scandir(rootdir) as rit:
        for entry in rit:
            if not entry.name.startswith('.') and entry.is_dir():
                dirlist.append(entry.path)
                dirlist += get_dirlist(entry.path)

    dirlist.sort() # Optional, in case you want sorted directory names
    return dirlist

请记住,这entry.path将使用子目录的绝对路径。如果只需要文件夹名称,则可以entry.name改用。有关该对象的更多详细信息,请参考os.DirEntryentry

I’ve had a similar question recently, and I found out that the best answer for python 3.6 (as user havlock added) is to use os.scandir. Since it seems there is no solution using it, I’ll add my own. First, a non-recursive solution that lists only the subdirectories directly under the root directory.

def get_dirlist(rootdir):

    dirlist = []

    with os.scandir(rootdir) as rit:
        for entry in rit:
            if not entry.name.startswith('.') and entry.is_dir():
                dirlist.append(entry.path)

    dirlist.sort() # Optional, in case you want sorted directory names
    return dirlist

The recursive version would look like this:

def get_dirlist(rootdir):

    dirlist = []

    with os.scandir(rootdir) as rit:
        for entry in rit:
            if not entry.name.startswith('.') and entry.is_dir():
                dirlist.append(entry.path)
                dirlist += get_dirlist(entry.path)

    dirlist.sort() # Optional, in case you want sorted directory names
    return dirlist

keep in mind that entry.path wields the absolute path to the subdirectory. In case you only need the folder name, you can use entry.name instead. Refer to os.DirEntry for additional details about the entry object.


回答 20

os.path.isdiros.listdir() 这样的东西使用过滤器功能filter(os.path.isdir,[os.path.join(os.path.abspath('PATH'),p) for p in os.listdir('PATH/')])

use a filter function os.path.isdir over os.listdir() something like this filter(os.path.isdir,[os.path.join(os.path.abspath('PATH'),p) for p in os.listdir('PATH/')])


回答 21

这将在文件树的右边列出所有子目录。

import pathlib


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

pathlib 是3.4版的新功能

This will list all subdirectories right down the file tree.

import pathlib


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

pathlib is new in version 3.4


回答 22

返回给定文件路径中所有子目录的列表的函数。将搜索整个文件树。

import os

def get_sub_directory_paths(start_directory, sub_directories):
    """
    This method iterates through all subdirectory paths of a given 
    directory to collect all directory paths.

    :param start_directory: The starting directory path.
    :param sub_directories: A List that all subdirectory paths will be 
        stored to.
    :return: A List of all sub-directory paths.
    """

    for item in os.listdir(start_directory):
        full_path = os.path.join(start_directory, item)

        if os.path.isdir(full_path):
            sub_directories.append(full_path)

            # Recursive call to search through all subdirectories.
            get_sub_directory_paths(full_path, sub_directories)

return sub_directories

Function to return a List of all subdirectories within a given file path. Will search through the entire file tree.

import os

def get_sub_directory_paths(start_directory, sub_directories):
    """
    This method iterates through all subdirectory paths of a given 
    directory to collect all directory paths.

    :param start_directory: The starting directory path.
    :param sub_directories: A List that all subdirectory paths will be 
        stored to.
    :return: A List of all sub-directory paths.
    """

    for item in os.listdir(start_directory):
        full_path = os.path.join(start_directory, item)

        if os.path.isdir(full_path):
            sub_directories.append(full_path)

            # Recursive call to search through all subdirectories.
            get_sub_directory_paths(full_path, sub_directories)

return sub_directories

回答 23

我们可以使用os.walk()获取所有文件夹的列表

import os

path = os.getcwd()

pathObject = os.walk(path)

这个pathObject是一个对象,我们可以通过

arr = [x for x in pathObject]

arr is of type [('current directory', [array of folder in current directory], [files in current directory]),('subdirectory', [array of folder in subdirectory], [files in subdirectory]) ....]

我们可以通过遍历arr并打印中间数组来获取所有子目录的列表

for i in arr:
   for j in i[1]:
      print(j)

这将打印所有子目录。

要获取所有文件:

for i in arr:
   for j in i[2]:
      print(i[0] + "/" + j)

we can get list of all the folders by using os.walk()

import os

path = os.getcwd()

pathObject = os.walk(path)

this pathObject is a object and we can get an array by

arr = [x for x in pathObject]

arr is of type [('current directory', [array of folder in current directory], [files in current directory]),('subdirectory', [array of folder in subdirectory], [files in subdirectory]) ....]

We can get list of all the subdirectory by iterating through the arr and printing the middle array

for i in arr:
   for j in i[1]:
      print(j)

This will print all the subdirectory.

To get all the files:

for i in arr:
   for j in i[2]:
      print(i[0] + "/" + j)

回答 24

具有给定父级的该函数以递归方式directory遍历其所有函数directories以及printsfilenames其中找到的所有函数。太有用了。

import os

def printDirectoryFiles(directory):
   for filename in os.listdir(directory):  
        full_path=os.path.join(directory, filename)
        if not os.path.isdir(full_path): 
            print( full_path + "\n")


def checkFolders(directory):

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

    #print(dir_list)

    for dir in dir_list:           
        print(dir)
        checkFolders(directory +"/"+ dir) 

    printDirectoryFiles(directory)       

main_dir="C:/Users/S0082448/Desktop/carpeta1"

checkFolders(main_dir)


input("Press enter to exit ;")

This function, with a given parent directory iterates over all its directories recursively and prints all the filenames which it founds inside. Too useful.

import os

def printDirectoryFiles(directory):
   for filename in os.listdir(directory):  
        full_path=os.path.join(directory, filename)
        if not os.path.isdir(full_path): 
            print( full_path + "\n")


def checkFolders(directory):

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

    #print(dir_list)

    for dir in dir_list:           
        print(dir)
        checkFolders(directory +"/"+ dir) 

    printDirectoryFiles(directory)       

main_dir="C:/Users/S0082448/Desktop/carpeta1"

checkFolders(main_dir)


input("Press enter to exit ;")


回答 25

通过从此处加入多个解决方案,这就是我最终使用的方法:

import os
import glob

def list_dirs(path):
    return [os.path.basename(x) for x in filter(
        os.path.isdir, glob.glob(os.path.join(path, '*')))]

By joining multiple solutions from here, this is what I ended up using:

import os
import glob

def list_dirs(path):
    return [os.path.basename(x) for x in filter(
        os.path.isdir, glob.glob(os.path.join(path, '*')))]

从子目录导入文件?

问题:从子目录导入文件?

我的档案tester.py位于/project

/project有一个名为的子目录lib,文件名为BoxTime.py

/project/tester.py
/project/lib/BoxTime.py

我想导入BoxTimetester。我已经试过了:

import lib.BoxTime

结果是:

Traceback (most recent call last):
  File "./tester.py", line 3, in <module>
    import lib.BoxTime
ImportError: No module named lib.BoxTime

任何想法如何BoxTime从子目录导入?

编辑

__init__.py是问题,但不要忘了提及BoxTime作为lib.BoxTime,或使用:

import lib.BoxTime as BT
...
BT.bt_function()

I have a file called tester.py, located on /project.

/project has a subdirectory called lib, with a file called BoxTime.py:

/project/tester.py
/project/lib/BoxTime.py

I want to import BoxTime from tester. I have tried this:

import lib.BoxTime

Which resulted:

Traceback (most recent call last):
  File "./tester.py", line 3, in <module>
    import lib.BoxTime
ImportError: No module named lib.BoxTime

Any ideas how to import BoxTime from the subdirectory?

EDIT

The __init__.py was the problem, but don’t forget to refer to BoxTime as lib.BoxTime, or use:

import lib.BoxTime as BT
...
BT.bt_function()

回答 0

在此处查看Packages文档(第6.4节):http : //docs.python.org/tutorial/modules.html

简而言之,您需要放置一个名为

__init__.py

在“ lib”目录中。

Take a look at the Packages documentation (Section 6.4) here: http://docs.python.org/tutorial/modules.html

In short, you need to put a blank file named

__init__.py

in the “lib” directory.


回答 1

  • 创建一个名为的子目录lib
  • 创建一个名为的空文件lib\__init__.py
  • 在中lib\BoxTime.py,编写如下函数foo()

    def foo():
        print "foo!"
    
  • 在上面目录中的客户机代码中lib,编写:

    from lib import BoxTime
    BoxTime.foo()
    
  • 运行您的客户端代码。你会得到:

    foo!

后来,在Linux中,它看起来像这样:

% cd ~/tmp
% mkdir lib
% touch lib/__init__.py
% cat > lib/BoxTime.py << EOF
heredoc> def foo():
heredoc>     print "foo!"
heredoc> EOF
% tree lib
lib
├── BoxTime.py
└── __init__.py

0 directories, 2 files
% python 
Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from lib import BoxTime
>>> BoxTime.foo()
foo!
  • Create a subdirectory named lib.
  • Create an empty file named lib\__init__.py.
  • In lib\BoxTime.py, write a function foo() like this:

    def foo():
        print "foo!"
    
  • In your client code in the directory above lib, write:

    from lib import BoxTime
    BoxTime.foo()
    
  • Run your client code. You will get:

    foo!
    

Much later — in linux, it would look like this:

% cd ~/tmp
% mkdir lib
% touch lib/__init__.py
% cat > lib/BoxTime.py << EOF
heredoc> def foo():
heredoc>     print "foo!"
heredoc> EOF
% tree lib
lib
├── BoxTime.py
└── __init__.py

0 directories, 2 files
% python 
Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from lib import BoxTime
>>> BoxTime.foo()
foo!

回答 2

您可以尝试将其插入sys.path

sys.path.insert(0, './lib')
import BoxTime

You can try inserting it in sys.path:

sys.path.insert(0, './lib')
import BoxTime

回答 3

我写下来是因为每个人似乎都建议您必须创建lib目录。

您无需命名子目录lib。你能说出它anything提供你把一个__init__.py进去。

您可以通过在Linux shell中输入以下命令来做到这一点:

$ touch anything/__init__.py 

所以现在您有了以下结构:

$ ls anything/
__init__.py
mylib.py

$ ls
main.py

然后,你可以导入mylibmain.py这样的:

from anything import mylib 

mylib.myfun()

您也可以像这样导入函数和类:

from anything.mylib import MyClass
from anything.mylib import myfun

instance = MyClass()
result = myfun()

您放置在其中的任何变量函数或类__init__.py也可以访问:

import anything

print(anything.myvar)

或像这样:

from anything import myvar

print(myvar)

I am writing this down because everyone seems to suggest that you have to create a lib directory.

You don’t need to name your sub-directory lib. You can name it anything provided you put an __init__.py into it.

You can do that by entering the following command in a linux shell:

$ touch anything/__init__.py 

So now you have this structure:

$ ls anything/
__init__.py
mylib.py

$ ls
main.py

Then you can import mylib into main.py like this:

from anything import mylib 

mylib.myfun()

You can also import functions and classes like this:

from anything.mylib import MyClass
from anything.mylib import myfun

instance = MyClass()
result = myfun()

Any variable function or class you place inside __init__.py can also be accessed:

import anything

print(anything.myvar)

Or like this:

from anything import myvar

print(myvar)

回答 4

您的lib目录是否包含__init__.py文件?

Python用于__init__.py确定目录是否为模块。

Does your lib directory contain a __init__.py file?

Python uses __init__.py to determine if a directory is a module.


回答 5

尝试import .lib.BoxTime。有关更多信息,请参阅PEP 328中的相对导入。

Try import .lib.BoxTime. For more information read about relative import in PEP 328.


回答 6

我这样做基本上涵盖了所有情况(确保您__init__.py在relative / path / to / your / lib / folder中):

import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/relative/path/to/your/lib/folder")
import someFileNameWhichIsInTheFolder
...
somefile.foo()


示例:
您在项目文件夹中:

/root/myproject/app.py

您在另一个项目文件夹中:

/root/anotherproject/utils.py
/root/anotherproject/__init__.py

您要使用/root/anotherproject/utils.py并调用其中的foo函数。

因此,您在app.py中编写:

import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/../anotherproject")
import utils

utils.foo()

I do this which basically covers all cases (make sure you have __init__.py in relative/path/to/your/lib/folder):

import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/relative/path/to/your/lib/folder")
import someFileNameWhichIsInTheFolder
...
somefile.foo()


Example:
You have in your project folder:

/root/myproject/app.py

You have in another project folder:

/root/anotherproject/utils.py
/root/anotherproject/__init__.py

You want to use /root/anotherproject/utils.py and call foo function which is in it.

So you write in app.py:

import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/../anotherproject")
import utils

utils.foo()

回答 7

__init__.py在子目录/ lib中创建一个空文件 。并在主代码的开头添加

from __future__ import absolute_import 

然后

import lib.BoxTime as BT
...
BT.bt_function()

或更好

from lib.BoxTime import bt_function
...
bt_function()

Create an empty file __init__.py in subdirectory /lib. And add at the begin of main code

from __future__ import absolute_import 

then

import lib.BoxTime as BT
...
BT.bt_function()

or better

from lib.BoxTime import bt_function
...
bt_function()

回答 8

只是这些答案的补充。

如果要从所有子目录导入所有文件,可以将其添加到文件的根目录。

import sys, os
sys.path.extend([f'./{name}' for name in os.listdir(".") if os.path.isdir(name)])

然后,您可以简单地从子目录中导入文件,就像这些文件位于当前目录中一样。

工作实例

如果我的项目中有以下目录及其子目录…

.
├── a.py
├── b.py
├── c.py
├── subdirectory_a
   ├── d.py
   └── e.py
├── subdirectory_b
   └── f.py
├── subdirectory_c
   └── g.py
└── subdirectory_d
    └── h.py

我可以将以下代码放入a.py文件中

import sys, os
sys.path.extend([f'./{name}' for name in os.listdir(".") if os.path.isdir(name)])

# And then you can import files just as if these files are inside the current directory

import b
import c
import d
import e
import f
import g
import h

换句话说,此代码将抽象出文件来自哪个目录。

Just an addition to these answers.

If you want to import all files from all subdirectories, you can add this to the root of your file.

import sys, os
sys.path.extend([f'./{name}' for name in os.listdir(".") if os.path.isdir(name)])

And then you can simply import files from the subdirectories just as if these files are inside the current directory.

Working example

If I have the following directory with subdirectories in my project…

.
├── a.py
├── b.py
├── c.py
├── subdirectory_a
│   ├── d.py
│   └── e.py
├── subdirectory_b
│   └── f.py
├── subdirectory_c
│   └── g.py
└── subdirectory_d
    └── h.py

I can put the following code inside my a.py file

import sys, os
sys.path.extend([f'./{name}' for name in os.listdir(".") if os.path.isdir(name)])

# And then you can import files just as if these files are inside the current directory

import b
import c
import d
import e
import f
import g
import h

In other words, this code will abstract from which directory the file is coming from.


回答 9

/project/tester.py

/project/lib/BoxTime.py

下一__init__.py行创建空白文件,直到找到文件

/project/lib/somefolder/BoxTime.py

#lib-需求有两个项目__init__.py,一个名为somefolder的目录 #somefolder有两个项目boxtime.py__init__.py

/project/tester.py

/project/lib/BoxTime.py

create blank file __init__.py down the line till you reach the file

/project/lib/somefolder/BoxTime.py

#lib — needs has two items one __init__.py and a directory named somefolder #somefolder has two items boxtime.py and __init__.py


回答 10

尝试这个:

from lib import BoxTime

try this:

from lib import BoxTime