2
votes

Comment obtenir le nom de fichier de la sous-classe?

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"?


1 commentaires

Les commentaires ne sont pas destinés à une discussion approfondie; cette conversation a été déplacée vers chat .


3 Réponses :


0
votes

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?


0 commentaires

1
votes

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()


2 commentaires

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.



4
votes

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__


0 commentaires