python: obter o diretório dois níveis acima


86

Ok ... Não sei onde xestá o módulo , mas sei que preciso colocar o caminho para o diretório dois níveis acima.

Então, há uma maneira mais elegante de fazer:

import os
two_up = os.path.dirname(os.path.dirname(__file__))

Soluções para Python 2 e 3 são bem-vindas!


1
Acho que sua solução está perfeitamente bem. Uma pathlibsolução é um pouco melhor e mais legível, mas não está incluída no Python 2.7. Eu diria que continue com o que você tem, talvez adicione um comentário.
jme

Talvez valha a pena adicionar a pip install pathlib2opção de manter a sanidade em 2.7.
Jonathan,

Respostas:


104

Você pode usar pathlib. Infelizmente, isso só está disponível no stdlib para Python 3.4. Se você tiver uma versão mais antiga, terá que instalar uma cópia do PyPI aqui . Isso deve ser fácil de usar pip.

from pathlib import Path

p = Path(__file__).parents[1]

print(p)
# /absolute/path/to/two/levels/up

Isso usa a parentssequência que fornece acesso aos diretórios pais e escolhe o segundo.

Note que pneste caso haverá alguma forma de Pathobjeto, com seus próprios métodos. Se você precisar dos caminhos como string, poderá chamá str-los.


Essa é uma boa resposta, obrigado e ótimo para py3. Para py2, não é possível nada melhor do que minha tentativa inicial, pois cria uma dependência extra
jramm

16
Essa não deve ser a resposta aceita, pois a Pathclasse parentsdepende do local de execução. Se você executar seu a __file__partir do diretório atual, a Pathclasse não terá pais. A resposta de @ Sebi2020 deve ser aceita ou seu método original deve ser usado. Eu acredito que seu método original é mais legível.
Red-Tune-84 de

1
Você pode precisar fazerp = Path(os.path.abspath(__file__)).parents[1]
Adam Raudonis

4
@AdamRaudonis Em vez de os.path.abspath, você também pode usarPath(__file__).resolve().parents[1]
Tulio Casagrande

7
Como @Kazanz mencionou, esta solução não funciona ao executar a partir de outros caminhos. A melhor solução é: p = Path(__file__).resolve().parents[1]. Eu também adicionei como uma resposta.
pythinker

46

Muito fácil:

Aqui está o que você deseja:

import os.path as path

two_up =  path.abspath(path.join(__file__ ,"../.."))

8
E talvez use em os.pardirvez de ...
jme

sys.argv [0] não retorna módulo que foi executado por python.exe? Então isso não funcionaria se o módulo no qual estou interessado fosse importado de algum outro pacote ... estou bem aqui?
jramm

Se você quiser usá-lo em um módulo, use __file__.
Sebi2020

1
@jme, você conhece um sistema operacional em que obtém o diretório pai com outra string diferente de ".." ???
Sebi2020

1
@ Sebi2020 Sim, notavelmente o antigo Mac OS. Aqui está uma lista: en.wikipedia.org/wiki/Path_(computing)
jme

22

Eu ia adicionar isso apenas para ser bobo, mas também porque mostra aos recém-chegados a utilidade potencial das funções de aliasing e / ou importações.

Depois de escrevê-lo, acho que este código é mais legível (ou seja, menor tempo para entender a intenção) do que as outras respostas até agora, e a legibilidade (geralmente) é rei.

from os.path import dirname as up

two_up = up(up(__file__))

Observação: você só deseja fazer esse tipo de coisa se seu módulo for muito pequeno ou contextualmente coeso.


14

A melhor solução (para python> = 3.4) ao executar a partir de qualquer diretório é:

from pathlib import Path
two_up = Path(__file__).resolve().parents[1]

10

Para aumentar os níveis do diretório 2:

 import os.path as path
 two_up = path.abspath(path.join(os.getcwd(),"../.."))

4

Pessoalmente, acho que usar o módulo os é o método mais fácil, conforme descrito abaixo. Se você estiver subindo apenas um nível, substitua ('../ ..') por ('..').

    import os
    os.chdir('../..')

--Check:
    os.getcwd()

1
É aceitável codificar o '/' que eu esperava ler os.chdir (os.join ('..', '..'))
GreenAsJade

2

Eu descobri que o seguinte funciona bem em 2.7.x

import os
two_up = os.path.normpath(os.path.join(__file__,'../'))

1

Você pode usar isso como uma solução genérica:

import os

def getParentDir(path, level=1):
  return os.path.normpath( os.path.join(path, *([".."] * level)) )

@JanSila: pode ser mais específico, por que não é pitônico? Para facilitar a leitura, poderia haver mais comentários sobre o que isso faz, sim - mas no final está usando recursos da linguagem python padrão, consulte, por exemplo, stackoverflow.com/questions/36901
Axel Heider

É um pouco denso, mas não acho que seja muito abstrato e ilegível. É apenas uma versão generalizada de outras respostas postadas aqui. Eu gostaria de uma maneira de biblioteca padrão de fazer as coisas, no entanto, sem a necessidade de implementar uma função.
Ryanjdillon

1

Mais implementação de plataforma cruzada será:

import pathlib
two_up = (pathlib.Path(__file__) / ".." / "..").resolve()

O uso parentnão é compatível com o Windows. Também é necessário adicionar .resolve(), a:

Torne o caminho absoluto, resolvendo todos os links simbólicos no caminho e também normalizando-o (por exemplo, transformando barras em barras invertidas no Windows)


2
Você tem uma fonte para parentnão trabalhar no Windows? Isso parece ter sido corrigido algum tempo desde que você escreveu este comentário. Funciona bem para mim usando Python 3.7.2 no Windows 10.
Nathan

Eu poderia começar a parenttrabalhar no Windows 10 com o Python 3.6.5. De qual versão de python você está falando @Zhukovgeen?
ggulgulia

@ggulgulia Eu acredito que foi 3,7
zhukovgreen

0

Supondo que você deseja acessar a pasta chamada xzy duas pastas até seu arquivo python. Isso funciona para mim e independente de plataforma.

".././xyz"


0

(pathlib.Path ('../../')) .resolve ()


Fornece o caminho relativo ao diretório de trabalho, não ao módulo
jramm 01 de

-1

Ainda não vejo uma resposta viável para o 2.7, que não requer a instalação de dependências adicionais e também começa a partir do diretório do arquivo. Não é bom como uma solução de linha única, mas não há nada de errado em usar os utilitários padrão.

import os

grandparent_dir = os.path.abspath(  # Convert into absolute path string
    os.path.join(  # Current file's grandparent directory
        os.path.join(  # Current file's parent directory
            os.path.dirname(  # Current file's directory
                os.path.abspath(__file__)  # Current file path
            ),
            os.pardir
        ),
        os.pardir
    )
)

print grandparent_dir

E para provar que funciona, começo aqui ~/Documents/notesapenas para mostrar que o diretório atual não influencia o resultado. Coloquei o arquivo grandpa.pycom esse script em uma pasta chamada "scripts". Ele rasteja até o diretório de documentos e, em seguida, para o diretório do usuário em um Mac.

(testing)AlanSE-OSX:notes AlanSE$ echo ~/Documents/scripts/grandpa.py 
/Users/alancoding/Documents/scripts/grandpa.py
(testing)AlanSE-OSX:notes AlanSE$ python2.7 ~/Documents/scripts/grandpa.py 
/Users/alancoding

Esta é a extrapolação óbvia da resposta para o dir pai . Melhor usar uma solução geral do que uma solução menos adequada em menos linhas.


-1

para py 3.4 e superior, pathlib

exemplo:

from pathlib import Path
path = Path("../../data/foo/someting.csv").resolve()

Isso fornece o caminho relativo ao diretório de trabalho, não ao módulo
jramm 01 de
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.