Pergunta

Eu estou tentando escrever um simples script Python que irá copiar um index.tpl para index.html em todos os subdiretórios (com algumas exceções).

Estou ficando atolados por tentar obter a lista de subdiretórios.

Foi útil?

Solução

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))]

Outras dicas

Por que ninguém mencionou glob ? glob permite usar expansão de nome Unix-style, e é minha a função para quase tudo o que precisa de encontrar mais do que um nome de caminho. Torna-se muito fácil:

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

Note que glob irá retornar o diretório com a barra final (como unix faria), enquanto a maioria das soluções baseadas path vai omitir a barra final.

Verifique " Obtendo uma lista de todos os subdiretórios no diretório atual ".

Aqui está uma versão Python 3:

import os

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

print(dir_list)
import os, os.path

Para obter (full-path) sub-diretórios imediatos em um diretório:

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

Para obter a última (mais recente) sub-diretório:

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

os.walk é seu amigo no esta situação.

Direto da documentação:

caminhada () gera os nomes de arquivos em uma árvore de diretórios, caminhando a árvore seja de cima para baixo ou para cima inferior. Para cada diretório na árvore com raiz no topo diretório (incluindo o próprio topo), que produz um 3-tupla (dirPath, dirnames, nomes de arquivos).

Este método bem faz tudo de uma vez.

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

Usando o módulo FilePath do Twisted:

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

Uma vez que alguns comentaristas pediram que as vantagens da utilização de bibliotecas de torcida para isso é, eu vou um pouco além da pergunta original aqui.


alguma documentação melhorada em um ramo que explica as vantagens de FilePath; você pode querer ler isso.

Mais especificamente neste exemplo: ao contrário da versão da biblioteca padrão, esta função pode ser implementado com não importações . A função "subdirs" é totalmente genérico, em que ela opera em nada, mas seu argumento. A fim de copiar e mover os arquivos usando a biblioteca padrão, você precisa depender do builtin "open", "listdir", talvez "isdir" ou "os.walk" ou "shutil.copy". Talvez "os.path.join" também. Sem mencionar o fato de que você precisa de uma seqüência passada um argumento para identificar o arquivo real. Vamos dar uma olhada na implementação integral que irá copiar "index.tpl" de cada diretório para "index.html":

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

A função "subdirs" acima pode funcionar em qualquer FilePath-como objeto. O que significa, entre outras coisas, ZipPath objetos. Infelizmente ZipPath é só de leitura no momento, mas pode ser estendido para a escrita de apoio.

Você também pode passar seus próprios objetos para fins de teste. A fim de testar as APIs-usando os.path sugeridas aqui, você tem que macaco com nomes importados e dependências implícitas e geralmente realizar a magia negra para obter seus testes para o trabalho. Com FilePath, você fazer algo como isto:

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(...))

Eu escrevi algum código para mover máquinas virtuais VMware em torno, e acabou usando os.path e shutil para realizar cópia de arquivos entre sub-diretórios.

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))

Não é terrivelmente elegante, mas ela não funciona.

Aqui está uma maneira:

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')
def get_folders_in_directories_recursively(self, 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

A função a seguir pode ser chamado como:

get_folders_in_directories_recursively (diretório, index = 1) -> fornece a lista de pastas no primeiro nível

get_folders_in_directories_recursively (diretório) -> dá todas as sub-pastas

Eu tenho que mencionar a path.py biblioteca, que eu uso muito frequentemente.

Buscando os subdiretórios imediatos se tornar tão simples como isso:

my_dir.dirs()

O exemplo de trabalho completo é:

from path import Path

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

subdirs = my_directory.dirs()

NB: my_directory ainda podem ser manipulados como uma cadeia de caracteres, uma vez que o caminho é uma subclasse de corda, mas proporcionando um grupo de métodos úteis para a manipulação de percursos

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

A função child_dirs toma um caminho um diretório e retorna uma lista de subdiretórios imediatos na mesma.

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')
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top