Как мне получить путь к файлу для класса в Python?


99

Учитывая класс C в Python, как я могу определить, в каком файле был определен класс? Мне нужно что-то, что может работать либо с классом C, либо с экземпляром с C.

Причина, по которой я это делаю, заключается в том, что я вообще фанат того, что файлы, которые принадлежат друг другу, находятся в одной папке. Я хочу создать класс, который использует шаблон Django для рендеринга себя как HTML. Базовая реализация должна вывести имя файла для шаблона на основе имени файла, в котором определен класс.

Скажем, я поместил класс LocationArtifact в файл «base / artifacts.py», затем я хочу, чтобы по умолчанию использовалось имя шаблона «base / LocationArtifact.html».



2
Они предполагают, что вы знаете модуль, который ищете в файле, у меня будет просто строка модуля, поскольку я работаю с реализациями вне класса.
Staale

Ответы:


136

Вы можете использовать модуль проверки , например:

import inspect
inspect.getfile(C.__class__)

1
Не уверен, что я делал по-другому, но вместо этого getfileя должен был использовать: inspect.getmodule(C.__class__)
AJP

4
Примечание: не работает с классами, созданными пользователем
Daniel Braun

8
Наверное, так и должно быть inspect.getfile(C). Если Cэто класс, то C.__class__ссылается на object, что вызовет исключение TypeError: <module 'builtins' (built-in)> is a built-in class. Я думаю, что только для экземпляра cвы хотите использовать inspect.getfile(c.__class__).
cheshirekow

1
Это не относится к классу, который расширяет абстрактный базовый класс ( metaclass=abc.ABCMeta), поскольку он возвращает /usr/local/lib/python3.7/abc.pyвместо соответствующего файла. Решение @JarretHardie (ниже) сработало лучше.
martian111 08

inspect.getfile (self .__ class__) работал у меня
diman82

37

пытаться:

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

1
Для того, чтобы получить путь от экземпляра C (по желанию) OP, замените LocationArtifactс , obj.__class__где OBJ является экземпляром LocationArtifact.
martian111 08

6

Это неправильный подход для Django и действительно форсирование вещей.

Типичный шаблон приложения Django:

  • / проект
    • /Название приложения
      • models.py
      • views.py
      • / шаблоны
        • index.html
        • и т.п.

1
+1: Делайте то, что Django делает естественным образом, и жизнь становится намного проще.
S.Lott

1
Согласовано. Django - одна из фреймворков с наименьшим количеством «магии», но шаблоны, теги шаблонов и приложения имеют определенные ожидания как часть своего шаблона. Если вам нужно делать дурацкий вывод классов, вы, вероятно, идете в неправильном направлении.
Soviut
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.