web-dev-qa-db-fra.com

Avec os.path de Python, comment puis-je accéder à un répertoire?

J'ai récemment mis à jour Django de v1.3.1 à v1.4.

Dans mon ancien settings.py j'ai

TEMPLATE_DIRS = (
    os.path.join(os.path.dirname( __file__ ), 'templates').replace('\\', '/'),
    # Put strings here, like "/home/html/Django_templates" or "C:/www/Django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
)

Cela désignera /Users/hobbes3/Sites/mysite/templates, mais car Django v1.4 a déplacé le dossier du projet au même niveau que les dossiers de l'application , mon fichier settings.py est maintenant dans /Users/hobbes3/Sites/mysite/mysite/ au lieu de /Users/hobbes3/Sites/mysite/.

Donc, en réalité, ma question est maintenant double:

  1. Comment utiliser os.path pour consulter un répertoire situé au-dessus de __file__. En d'autres termes, je veux que /Users/hobbes3/Sites/mysite/mysite/settings.py trouve /Users/hobbes3/Sites/mysite/templates en utilisant des chemins relatifs.
  2. Devrais-je conserver le dossier template (qui contient des modèles d'application croisés, comme admin, registration, etc.) au niveau du projet /User/hobbes3/Sites/mysite ou à /User/hobbes3/Sites/mysite/mysite?
184
hobbes3
os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'templates'))

En ce qui concerne l'emplacement du dossier des modèles, je ne le sais pas car Django 1.4 vient de paraître et je ne l'ai pas encore regardé. Vous devriez probablement poser une autre question sur SE pour résoudre ce problème.

Vous pouvez également utiliser normpath pour nettoyer le chemin plutôt que abspath. Cependant, dans cette situation, Django attend un chemin absolu plutôt qu'un chemin relatif.

Pour la compatibilité entre plates-formes, utilisez os.pardir au lieu de '..'.

247
forivall

Pour obtenir le dossier d'un fichier, utilisez simplement:

os.path.dirname(path) 

Pour ouvrir un dossier, utilisez à nouveau os.path.dirname

os.path.dirname(os.path.dirname(path))

Vous voudrez peut-être vérifier si __file__ est un lien symbolique:

if os.path.islink(__file__): path = os.readlink (__file__)
78
locojay

Vous voulez exactement ceci:

BASE_DIR = os.path.join( os.path.dirname( __file__ ), '..' )
14
Alan Viars

Personnellement, j'opterais pour la fonction

def get_parent_dir(directory):
    import os
    return os.path.dirname(directory)

current_dirs_parent = get_parent_dir(os.getcwd())
9
Lord Sumner

Si vous utilisez Python 3.4 ou une version plus récente, un moyen pratique de déplacer plusieurs répertoires vers le haut est pathlib :

from pathlib import Path

full_path = "path/to/directory"
str(Path(full_path).parents[0])  # "path/to"
str(Path(full_path).parents[1])  # "path"
str(Path(full_path).parents[2])  # "."
7
birnbaum

Je pense que la meilleure chose à faire est de réutiliser dirname () pour pouvoir appeler

os.path.dirname(os.path.dirname( __file__ ))

si votre fichier est à /Users/hobbes3/Sites/mysite/templates/method.py

Cela retournera "/ Users/hobbes3/Sites/mysite"

6
pythonHelpRequired

Cela peut être utile dans les autres cas où vous souhaitez ouvrir x dossiers. Il suffit de lancer walk_up_folder(path, 6) pour monter 6 dossiers.

def walk_up_folder(path, depth=1):
    _cur_depth = 1        
    while _cur_depth < depth:
        path = os.path.dirname(path)
        _cur_depth += 1
    return path   
6
Marcus Krautwurst
from os.path import dirname, realpath, join
join(dirname(realpath(dirname(__file__))), 'templates')

Mise à jour:

Si vous "copiez" settings.py par le biais de liens symboliques, la réponse de @ forivall est meilleure:

~user/
    project1/  
        mysite/
            settings.py
        templates/
            wrong.html

    project2/
        mysite/
            settings.py -> ~user/project1/settings.py
        templates/
            right.html

La méthode ci-dessus "verra" wrong.html tandis que la méthode de @ forivall verra right.html

En l'absence de liens symboliques, les deux réponses sont identiques.

6
Antony Hatchkins

Pour un paranoïaque comme moi, je préférerais celui-ci

TEMPLATE_DIRS = (
    __file__.rsplit('/', 2)[0] + '/templates',
)
2
haterh

Pour aller n dossiers vers le haut ... exécutez up(n)

import os

def up(n, nth_dir=os.getcwd()):
    while n != 0:
        nth_dir = os.path.dirname(nth_dir)
        n -= 1
    return nth_dir
1
Jo3l

Bien sûr: utilisez simplement os.chdir(..).

0
The Shwarma