web-dev-qa-db-fra.com

Comment obtenir le chemin / nom du module en cours d'exécution

J'ai cherché et cela semble être une question simple sans réponse simple.

J'ai le fichier a/b/c.py qui serait appelé avec python -m a.b.c. Je souhaite obtenir la valeur a.b.c au niveau du module.


USAGE = u'''\
Usage:
    python -m %s -h
''' % (what_do_i_put_here,)

Donc, quand je reçois le -h option, j'affiche le USAGE sans avoir besoin d'écrire réellement la valeur réelle dans chaque script.

Dois-je vraiment passer par inspect pour obtenir la valeur souhaitée?

Merci.

EDIT: Comme dit, il y a des réponses (j'ai cherché), mais pas des réponses simples. Soit inspect, soit traceback, soit manipulez __file__ et __package__ et faites une sous-chaîne pour obtenir la réponse. Mais rien de plus simple que si j'avais une classe dans le module, je pouvais simplement utiliser myClass.__module__ et j'obtiendrais la réponse que je veux. L'utilisation de __name__ est (malheureusement) inutile car c'est toujours __main__.

En outre, c'est dans python 2.6 et je ne peux pas utiliser d'autres versions.

32
Danosaure

Cela fonctionne pour moi:

__loader__.fullname

Aussi, si je fais python -m b.c à partir d'un\j'obtiens 'b.c' comme prévu.

Je ne sais pas exactement ce qu'est l'attribut __loader__, alors faites-moi savoir si ce n'est pas bon.

edit : Cela vient de PEP 302: http://www.python.org/dev/peps/pep-0302/ =

Extraits intéressants du lien:

La méthode load_module () a quelques responsabilités qu'elle doit remplir avant elle exécute n'importe quel code:

...

  • Il doit ajouter un attribut __loader__ au module, défini sur l'objet loader. C'est principalement pour l'introspection, mais peut être utilisé pour des extras spécifiques à l'importateur, par exemple pour obtenir des données associées à un importateur.

Il semble donc que cela devrait fonctionner correctement dans tous les cas.

26
Shawabawa

Je pense que vous cherchez en fait le __name__ variable spéciale. De la documentation Python :

Dans un module, le nom du module (sous forme de chaîne) est disponible comme valeur de la variable globale __name__.

Si vous exécutez un fichier directement, ce nom sera __main__. Cependant, si vous êtes dans un module (comme dans le cas où vous utilisez l'indicateur -m, ou toute autre importation), ce sera le nom complet du module.

11
Chris Phillips

Lorsqu'il est exécuté avec -m, sys.path[0] contient le chemin complet du module. Vous pouvez l'utiliser pour construire le nom.

source: http://docs.python.org/using/cmdline.html#command-line

Une autre option peut être le __package__ variable intégrée qui est disponible dans les modules.

8
dappawit

La seule façon est de manipuler les chemins avec os.getcwd (), os.path, file et ainsi de suite, comme vous l'avez mentionné.

En fait, ce pourrait être un bon correctif à implémenter pour optparse/argparse (qui remplace actuellement "% prog" dans la chaîne d'utilisation par os.path.basename (sys.argv [0]) - vous utilisent optparse, non? -), c'est-à-dire une autre chaîne spéciale comme% module.

1
Giacomo Lacava

Nombre d'options sont disponibles pour obtenir le chemin/nom du module en cours.

Familiarisez-vous d'abord avec l'utilisation de __ fichier __ en Python, Cliquez ici pour voir l'utilisation .

Il contient le nom du module actuellement chargé .

Vérifiez/essayez le code suivant, il fonctionnera à la fois Python2 & Python3 .

# module_names.py 

import os

print (__file__)
print (os.path.abspath(__file__))
print (os.path.realpath(__file__))

Sortie sur MAC OS X:

MacBook-Pro-2:practice admin$ python module_names.py 
module_names.py
/Users/admin/projects/Python/python-the-snake/practice/module_names.py
/Users/admin/projects/Python/python-the-snake/practice/module_names.py

Nous avons donc ici le nom du nom du module actuel et son chemin absolu .

0
hygull

Je ne vois pas pourquoi il existe une restriction telle que "python -m a.b.c". Bien sûr, le module réel pourrait être à l'intérieur de Zip ou autre, mais je préfère simplifier toute l'approche avec un script wrapper, qui garantit que l'exécution se déroule dans le bon contexte, avec right python exemple.

L'emballage peut contenir aussi peu que:

import sys
__import__(sys.argv[1])

Ensuite, vous pouvez utiliser votre méthode préférée pour obtenir le nom du module à utiliser.

retour à l'exigence d'origine. Si j'ai bien compris, l'idée est que quelqu'un exécute un fichier python dans un sous-sous-répertoire pour découvrir à partir du message d'utilisation qu'il s'agit vraiment d'un module de some.mega.package.

Je pense qu'il n'y a pas de moyen générique fiable pour déterminer si l'on veut exécuter le module c, bc ou abc, sans une analyse du système de fichiers avec certaines heuristiques (disons, trouver tous les __init__.py dans les répertoires externes jusqu'à ce qu'il n'y ait pas de points plus __init__.py), et même avec l'analyse ce n'est pas 100%.

0
Roman Susi