Come ottengo il percorso file per una classe in Python?


95

Data una classe C in Python, come posso determinare in quale file è stata definita la classe? Ho bisogno di qualcosa che possa funzionare dalla classe C o da un'istanza fuori C.

Il motivo per cui lo sto facendo è perché generalmente sono un fan del mettere i file che appartengono insieme nella stessa cartella. Voglio creare una classe che utilizzi un template Django per renderizzarsi come HTML. L'implementazione di base dovrebbe dedurre il nome del file per il modello in base al nome del file in cui è definita la classe.

Diciamo che ho inserito una classe LocationArtifact nel file "base / artifacts.py", quindi voglio che il comportamento predefinito sia che il nome del modello sia "base / LocationArtifact.html".



2
Quelli presumono che tu conosca il modulo per il quale stai cercando il file, avrò solo la stringa del modulo mentre lavoro con le implementazioni di una classe.
Staale

Risposte:


130

Puoi usare il modulo inspect , in questo modo:

import inspect
inspect.getfile(C.__class__)

1
Non sono sicuro di cosa stessi facendo di diverso ma invece getfileho dovuto usare: inspect.getmodule(C.__class__)
AJP

4
Nota: non funziona su classi create dall'utente
Daniel Braun

6
Probabilmente dovrebbe essere così inspect.getfile(C). Se Cè una classe, si C.__class__riferisce a object, il che solleverà un'eccezione TypeError: <module 'builtins' (built-in)> is a built-in class. Penso che solo per un'istanza cvuoi usare inspect.getfile(c.__class__).
cheshirekow

1
Questo non è stato fatto per una classe che estende una classe base astratta ( metaclass=abc.ABCMeta), poiché restituisce al /usr/local/lib/python3.7/abc.pyposto del file appropriato. La soluzione di @JarretHardie (sotto) ha funzionato meglio.
martian111

36

provare:

import sys, os
os.path.abspath(sys.modules[LocationArtifact.__module__].__file__)

1
Per ottenere il percorso da un'istanza di C (come desiderato dall'OP), sostituire LocationArtifactcon obj.__class__dove obj è un'istanza di LocationArtifact.
Martian111

5

Questo è l'approccio sbagliato per Django e forza davvero le cose.

Il tipico pattern di app Django è:

  • /progetto
    • /nome dell'applicazione
      • models.py
      • views.py
      • / templates
        • index.html
        • eccetera.

1
+1: Fai quello che Django fa naturalmente e la vita è molto più semplice.
S.Lott

1
Concordato. Django è uno dei framework con la minor quantità di "magia", ma i template, i tag template e le app hanno alcune aspettative come parte del loro pattern. Se devi fare un'inferenza di classe stravagante, probabilmente stai andando nella direzione sbagliata.
Soviut
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.