Estou tentando aprender python e estou fazendo um programa que irá gerar um script. Quero usar os.path.join, mas estou muito confuso. De acordo com a documentação, se eu disser:
os.path.join('c:', 'sourcedir')
Eu entendo "C:sourcedir"
. Segundo a documentação, isso é normal, certo?
Mas quando eu uso o comando copytree, o Python irá gerar a saída da maneira desejada, por exemplo:
import shutil
src = os.path.join('c:', 'src')
dst = os.path.join('c:', 'dst')
shutil.copytree(src, dst)
Aqui está o código de erro que recebo:
WindowsError: [Erro 3] O sistema não pode encontrar o caminho especificado: 'C: src /*.*'
Se eu embrulhar os.path.join
com os.path.normpath
, obtenho o mesmo erro.
Se isso os.path.join
não pode ser usado dessa forma, fico confuso quanto ao seu propósito.
De acordo com as páginas sugeridas por Stack Overflow, barras não devem ser usadas na junção - correto, presumo?
fonte
os.path.join
ouos.sep
se você vai especificar dec:
qualquer maneira?c:
não faz sentido em outros sistemas operacionais.os.path.join('c:','folder')
funciona de forma diferenteos.path.join('folder','file')
? É por causa de:
ou porque 'c: `é uma unidade?Para ser ainda mais pedante, a resposta mais consistente do python doc seria:
Já que você também precisa de os.sep para o caminho raiz posix:
fonte
os.sep
superior?os.sep
. Ele só funciona após a letra da unidade vazia. >>> os.path.join ("C: \ adeus", os.sep, "temp") 'C: \\ temp'os.sep
é útil quando você deseja manipular caminhos sem fazer suposições sobre o separador. É inútil usar comos.path.join()
ele, pois já conhece o separador correto. Também é inútil se você acabar precisando especificar explicitamente o diretório raiz por nome (como você pode ver em seu próprio exemplo). Por que fazer em"c:" + os.sep
vez de simplesmente"c:\\"
ou emos.sep + "usr"
vez de simplesmente"/usr"
? Observe também que nos shells do Win você nãocd c:
podecd c:\
, mas pode , sugerindo que o nome da raiz é realmentec:\
.O motivo de
os.path.join('C:', 'src')
não estar funcionando conforme o esperado é algo na documentação que você vinculou a:Como o ghostdog disse, você provavelmente quer
mypath=os.path.join('c:\\', 'sourcedir')
fonte
Para ser pedante, provavelmente não é bom codificar / ou \ como separador de caminho. Talvez isso seja melhor?
ou
fonte
Para uma solução independente de sistema que funciona em Windows e Linux, não importa o caminho de entrada, pode-se usar
os.path.join(os.sep, rootdir + os.sep, targetdir)
No Windows:
No Linux:
fonte
c:
não existe no * nix eusr
não existe no Windows ..os.path.join(os.sep, rootdir + os.sep, targetdir)
é agnóstica do sistema precisamente porque funciona com ambos os exemplos específicos do sistema, sem a necessidade de alterar o código.rootdir = "usr" if nix else "c:"
. Mas o mais direto e precisorootdir = "/usr" if nix else "c:\\"
funciona da mesma forma, sem asos.sep
acrobacias e consequentes coçar a cabeça. Não há perigo de que um diretório raiz em * nix comece com qualquer coisa diferente de uma barra, ou que o Windows tenha diretórios raiz nomeados sem dois-pontos finais e barra invertida (por exemplo, em shells do Win, você não pode simplesmente fazercd c:
, você precisa especificar a barra invertida final), então por que fingir o contrário?Eu diria que este é um bug do Python (Windows).
Por que bug?
Eu acho que esta declaração deveria ser
True
Mas é
False
em máquinas Windows.fonte
para entrar em um caminho do Windows, tente
basicamente, você precisará escapar da barra
fonte
Você tem algumas abordagens possíveis para tratar o caminho no Windows, desde as mais codificadas (como o uso de literais de string brutas ou barras invertidas de escape) até as menos importantes. Aqui estão alguns exemplos que funcionarão conforme o esperado. Use o que melhor se adapta às suas necessidades.
fonte
Consentimento com @ georg-
Eu diria então por que precisamos de coxo
os.path.join
- melhor usarstr.join
ou,unicode.join
por exemplo,fonte
respondendo ao seu comentário: "os outros '//' 'c:', 'c: \\' não funcionaram (C: \\ criou duas barras invertidas, C: \ não funcionou de todo)"
No Windows, o uso de
os.path.join('c:', 'sourcedir')
irá adicionar automaticamente duas barras invertidas\\
na frente do código-fonte .Para resolver o caminho, como o python funciona no Windows também com barras -> '/' , basta adicionar
.replace('\\','/')
comos.path.join
como abaixo: -os.path.join('c:\\', 'sourcedir').replace('\\','/')
por exemplo:
os.path.join('c:\\', 'temp').replace('\\','/')
saída: 'C: / temp'
fonte
As soluções propostas são interessantes e oferecem uma boa referência, porém são apenas parcialmente satisfatórias. É normal adicionar manualmente o separador quando você tem um único caso específico ou sabe o formato da string de entrada, mas pode haver casos em que você deseja fazer isso programaticamente em entradas genéricas.
Com um pouco de experimentação, acredito que o critério é que o delimitador de caminho não seja adicionado se o primeiro segmento for uma letra de unidade, ou seja, uma única letra seguida de dois pontos, não importa se corresponde a uma unidade real.
Por exemplo:
Uma maneira conveniente de testar os critérios e aplicar uma correção de caminho pode ser usar a
os.path.splitdrive
comparação do primeiro elemento retornado com o valor de teste, comot+os.path.sep if os.path.splitdrive(t)[0]==t else t
.Teste:
provavelmente pode ser melhorado para ser mais robusto para espaços à direita, e eu testei apenas no Windows, mas espero que dê uma ideia. Veja também Os.path: você pode explicar esse comportamento? para detalhes interessantes sobre sistemas diferentes do Windows.
fonte