2010-05-12 18 views
94

este código es obtener el templates/blog1/pagina.html en b.py:Cómo obtener la ubicación El directorio padre

path = os.path.join(os.path.dirname(__file__), os.path.join('templates', 'blog1/page.html')) 

pero quiero obtener la ubicación El directorio padre:

y cómo conseguir la ubicación aparent

gracias

actualización:

esto es correcto:

dirname=os.path.dirname 
path = os.path.join(dirname(dirname(__file__)), os.path.join('templates', 'blog1/page.html')) 

o

path = os.path.abspath(os.path.join(os.path.dirname(__file__),"..")) 
+2

¿Desea obtener 'blog1' o' a'? ¿Y dónde está ubicado su archivo actual? –

+0

¿entiendes lo que está haciendo tu código? – SilentGhost

+1

sí, obtiene las plantillas/blog1/page.html – zjm1126

Respuesta

114

Usted puede aplicar nombredir varias veces para subir más alto: dirname(dirname(file)). Sin embargo, esto solo puede ir tan lejos como el paquete raíz. Si esto es un problema, use os.path.abspath: dirname(dirname(abspath(file))).

+1

parece saber sobre 'dirname' – SilentGhost

+29

Sé que OP sabe sobre' dirname'. No es obvio para todos que la aplicación de dirname a un directorio produce el directorio principal. –

+0

hola Marcelo, mira el actualizado – zjm1126

3

¿Puede unir dos carpetas .. para obtener el elemento primario de la carpeta principal?

path = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)),"..","..")) 
9
os.path.dirname(os.path.abspath(__file__)) 

debe darle la ruta de acceso a a.

Pero si b.py es el archivo que se ejecuta actualmente, entonces se puede lograr el mismo con sólo hacer

os.path.abspath(os.path.join('templates', 'blog1', 'page.html')) 
+1

o, lo sé, tienes razón, y quiero obtener la carpeta padre de a. cómo conseguirlo – zjm1126

+0

@ zjm1126: Ver la respuesta de Marcelo Cantos. Aplica 'dirname()' dos veces. Todo lo que necesita ahora debe estar en este sitio. –

37

os.path.abspath no valida nada, por lo que si ya estamos añadiendo cuerdas a __file__ no hay necesita molestarse con dirname o unirse o algo así. Sólo tratar __file__ como un directorio y comenzar a subir:

# climb to __file__'s parent's parent: 
os.path.abspath(__file__ + "/../../") 

Eso es mucho menos complicado que os.path.abspath(os.path.join(os.path.dirname(__file__),"..")) y casi tan manejable como dirname(dirname(__file__)). Escalar más de dos niveles comienza a ser ridículo.

Pero, ya que sabemos cuántos niveles se suba, podríamos limpiar esto con un poco simple función:

uppath = lambda _path, n: os.sep.join(_path.split(os.sep)[:-n]) 

# __file__ = "/aParent/templates/blog1/page.html" 
>>> uppath(__file__, 1) 
'/aParent/templates/blog1' 
>>> uppath(__file__, 2) 
'/aParent/templates' 
>>> uppath(__file__, 3) 
'/aParent' 
+0

Me gusta esta respuesta mejor^ – Stephen

+0

Excelente enfoque – MA1

+2

Esto es bueno, pero también sería bueno si la biblioteca estándar agregó una función de conveniencia que lo logró ... no quiero venir a SO cada vez que necesito este func – gradi3nt

2

Una manera simple puede ser:

import os 
current_dir = os.path.abspath(os.path.dirname(__file__)) 
parent_dir = os.path.abspath(current_dir + "/../") 
print parent_dir 
7

os.pardir es una mejor manera para ../ y más legible.

import os 
print os.path.abspath(os.path.join(given_path, os.pardir)) 

Esto devolverá la ruta padre del given_path

0

creo uso esto es mejor:

os.path.realpath(__file__).rsplit('/', X)[0] 


In [1]: __file__ = "/aParent/templates/blog1/page.html" 

In [2]: os.path.realpath(__file__).rsplit('/', 3)[0] 
Out[3]: '/aParent' 

In [4]: __file__ = "/aParent/templates/blog1/page.html" 

In [5]: os.path.realpath(__file__).rsplit('/', 1)[0] 
Out[6]: '/aParent/templates/blog1' 

In [7]: os.path.realpath(__file__).rsplit('/', 2)[0] 
Out[8]: '/aParent/templates' 

In [9]: os.path.realpath(__file__).rsplit('/', 3)[0] 
Out[10]: '/aParent' 
+0

No del todo, depende del sistema operativo (no funcionará en Windows). Tampoco permite el uso de rutas relativas. – kgadek

0

Aquí hay otra solución relativamente simple que:

  • no lo hace use dirname() (que no funciona como se esperaba en argumentos de un nivel como "file.txt" o padres relativos como "..")
  • no utiliza abspath() (evitando ninguna hipótesis sobre el directorio de trabajo actual), sino que conserva el carácter relativo de caminos

que sólo utiliza normpath y join:

def parent(p): 
    return os.path.normpath(os.path.join(p, os.path.pardir)) 

# Example: 
for p in ['foo', 'foo/bar/baz', 'with/trailing/slash/', 
     'dir/file.txt', '../up/', '/abs/path']: 
    print parent(p) 

Resultado:

. 
foo/bar 
with/trailing 
dir 
.. 
/abs 
0

Intenté:

import os 
os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))), os.pardir)) 
3

la siguiente manera para saltar a la carpeta anterior:

os.chdir(os.pardir) 

Si necesita múltiples saltos una solución buena y fácil será utilizar un decorador simple en este caso.

12

Usted puede utilizar el módulo pathlib en Python 3.4+:

from pathlib import Path 

Path(__file__).parent 

Puede utilizar varias llamadas a parent ir más lejos en el camino:

Path(__file__).parent.parent 

Como alternativa a la fijación parent dos veces , puede usar

Path(__file__).parents[1] 
Cuestiones relacionadas