210 votes

Python - comment faire référence aux chemins relatifs des ressources lorsque vous travaillez avec le référentiel de code

Nous travaillons avec un référentiel de code qui est déployée à la fois pour windows et linux, parfois sur des répertoires différents. Comment doit-on des modules à l'intérieur du projet, reportez-vous à l'un des non-python ressources dans le projet (fichier CSV, etc.)? Si nous faisons quelque chose comme

thefile=open('test.csv')

ou

thefile=open('../somedirectory/test.csv')

Il ne fonctionne que lorsque le script est exécuté à partir d'un répertoire spécifique, ou un sous-ensemble de répertoires. Ce que j'aimerais faire, c'est quelque chose comme:

path=getBasePathOfProject()+'/somedirectory/test.csv'
thefile=open(path)

Est-ce la bonne manière? Est-il possible? Merci

285voto

c089 Points 1752

Essayez d'utiliser un nom de fichier relatif au chemin de fichiers actuel. Exemple pour './my_file':

 fn = os.path.join(os.path.dirname(__file__), 'my_file')
 

50voto

Sharoon Thomas Points 616

Si vous utilisez le programme d'installation d'outils ou de distribuer (un setup.py installer), puis la "bonne" façon d'accéder à ces emballé les ressources semblent être à l'aide de package_resources.

Dans votre cas, l'exemple serait

import pkg_resources
my_data = pkg_resources.resource_string(__name__, "foo.dat")

Qui, bien sûr, se lit la ressource et la lecture de données binaires serait la valeur de my_data

Si vous avez besoin seulement le nom de fichier vous pouvez également utiliser

resource_filename(package_or_requirement, resource_name)

Exemple:

resource_filename("MyPackage","foo.dat")

L'avantage est qu'une garantie de travail, même si c'est une archive de distribution comme un œuf.

Voir http://packages.python.org/distribute/pkg_resources.html#resourcemanager-api

15voto

user137673 Points 867

J'utilise souvent quelque chose de similaire à ceci:

import os
DATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), 'datadir'))

# if you have more paths to set, you might want to shorten this as
here = lambda x: os.path.abspath(os.path.join(os.path.dirname(__file__), x))
DATA_DIR = here('datadir') 

pathjoin = os.path.join
# ...
# later in script
for fn in os.listdir(DATA_DIR):
    f = open(pathjoin(DATA_DIR, fn))
    # ...

La variable

__file__

détient le nom de fichier du script de vous écrire ce code, vous pouvez faire des chemins d'accès relatifs à un script, mais toujours écrites avec des chemins absolus. Il fonctionne très bien pour plusieurs raisons:

  • le chemin est absolu, mais encore par rapport
  • le projet peut encore être déployés dans un conteneur

Mais vous avez besoin de regarder pour la plate-forme de compatibilité de Windows os.pathsep est différent de celui d'UNIX.

6voto

gavoja Points 202
 import os
cwd = os.getcwd()
path = os.path.join(cwd, "my_file")
f = open(path)
 

Vous essayez également de normaliser votre cwd utilisant os.path.abspath(os.getcwd()) . Plus d'infos ici .

2voto

Achim Points 6912

Vous pouvez utiliser la variable de construction __file__ . Il contient le chemin du fichier actuel. J'implémenterais getBaseOfProject dans un module à la racine de votre projet. Là, j'obtiendrais la partie du chemin de __file__ et le renverrais. Cette méthode peut ensuite être utilisée partout dans votre projet.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X