Comment obtenir le nom de fichier de la sous-classe?
Exemple:
base.py
:
from base import BaseClass class MainClass1(BaseClass): pass
main1.py
:
class BaseClass: def __init__(self): # How to get the path "./main1.py"?
3 Réponses :
Je pense que vous cherchez le mauvais mécanisme pour votre solution. Vos commentaires suggèrent que ce que vous voulez, c'est un gestionnaire d'exceptions avec une capacité de traçage minimale. Ce n'est pas quelque chose de facile à gérer dans le mécanisme général de la classe
.
Vous devriez plutôt vous pencher sur les capacités d'inspection de pile de Python. Très simplement, vous voulez que votre méthode __init__
rapporte le nom de fichier de la sous-classe appelante. Vous pouvez marteler cela en demandant à l'appelant de transmettre sa propre valeur __file__
. De manière automatisée, vous pouvez creuser un cadre de pile et accéder à __file__
via cet enregistrement de contexte. Notez que cette approche suppose que le seul moment où vous avez besoin de ces informations, c'est lorsque __init__
est appelé directement à partir d'une méthode de sous-classe.
Est-ce suffisant pour vous amener à la bonne documentation?
Vous pouvez le faire en retournant à travers la pile appelante pour obtenir l'espace de noms global de l'appelant de la méthode BaseClass .__ init __ ()
, et à partir de là, vous pouvez extraire le nom du fichier qu'il est en utilisant la valeur de la clé __file__
.
Voici ce que je veux dire:
base.py
:
XXX
main1.py
:
In BaseClass.__init__() callers_path: the\path\to\main1.py
Exemple de sortie de l'exécution de main1.py
:
from base import BaseClass class MainClass1(BaseClass): def __init(self): super().__init__() mainclass1 = MainClass1()
Merci mais python imprime le niveau 3r des composants: (index.py) sans le MainClass1
. Mais votre réponse fonctionne avec l'exemple mais pas avec mon projet. Merci quand même. La MainClass1 est appelée dinamicaly en utilisant importlib.util
.
Il est possible de revenir à plus d'un niveau de la pile d'appels, donc je pense qu'il serait possible de gérer votre situation. Si vous modifiez le code de votre question pour qu'il corresponde à votre vrai code, je pourrai peut-être vous montrer comment le faire.
N'oubliez pas que self
dans BaseClass .__ init__
est une instance de la classe réelle en cours d'initialisation. Par conséquent, une solution est de demander à cette classe de quel module elle provient, puis du chemin d'accès à ce module:
class BaseClass: def __init__(self): print "{}.{}".format( self.__module__, self.__class__.__name__ )
Je pense qu'il y a probablement un certain nombre de façons dont vous pourriez vous retrouver avec un module que vous ne pouvez pas importer cependant; cela ne semble pas être la solution la plus robuste.
Si tout ce que vous essayez de faire est d'identifier d'où vient la sous-classe, alors il suffit probablement de combiner le nom du module et le nom de la classe, puisque doit l'identifier de manière unique:
import importlib class BaseClass: def __init__(self): m = importlib.import_module(self.__module__) print m.__file__
Les commentaires ne sont pas destinés à une discussion approfondie; cette conversation a été déplacée vers chat .