Bagaimana cara mendapatkan jalur file untuk kelas dengan Python?

95

Diberikan kelas C dengan Python, bagaimana saya bisa menentukan di file mana kelas itu didefinisikan? Saya membutuhkan sesuatu yang dapat bekerja baik dari kelas C, atau dari contoh di luar C.

Alasan saya melakukan ini, adalah karena saya biasanya penggemar meletakkan file yang dimiliki bersama dalam folder yang sama. Saya ingin membuat kelas yang menggunakan cetakan Django untuk membuat dirinya sendiri sebagai HTML. Implementasi dasar harus menyimpulkan nama file untuk template berdasarkan nama file yang ditentukan kelasnya.

Katakanlah saya meletakkan LocationArtifact kelas di file "base / artifacts.py", maka saya ingin perilaku defaultnya adalah bahwa nama template adalah "base / LocationArtifact.html".

Staale
sumber
2
Mereka menganggap Anda tahu modul yang Anda cari file-nya, saya hanya akan memiliki string modul saat saya bekerja dengan implementasi dari kelas.
Staale

Jawaban:

131

Anda dapat menggunakan modul inspect , seperti ini:

import inspect
inspect.getfile(C.__class__)
DNS
sumber
1
Tidak yakin apa yang saya lakukan berbeda tetapi getfilesaya harus menggunakan: inspect.getmodule(C.__class__)
AJP
4
Catatan: tidak berfungsi pada kelas yang dibuat oleh pengguna
Daniel Braun
7
Ini mungkin seharusnya inspect.getfile(C). Jika Cadalah kelas, maka C.__class__mengacu ke object, yang akan memunculkan pengecualian TypeError: <module 'builtins' (built-in)> is a built-in class. Saya pikir hanya untuk contoh cyang ingin Anda gunakan inspect.getfile(c.__class__).
cheshirekow
1
Ini tidak untuk kelas yang memperluas kelas dasar abstrak ( metaclass=abc.ABCMeta), karena ia mengembalikan /usr/local/lib/python3.7/abc.pyalih-alih file yang sesuai. Solusi dari @JarretHardie (di bawah) bekerja lebih baik.
martian111
36

mencoba:

import sys, os
os.path.abspath(sys.modules[LocationArtifact.__module__].__file__)
Jarret Hardie
sumber
1
Untuk mendapatkan path dari instance C (seperti yang diinginkan oleh OP), ganti LocationArtifactdengan obj.__class__where obj adalah instance LocationArtifact.
martian111
5

Ini adalah pendekatan yang salah untuk Django dan benar-benar memaksakan sesuatu.

Pola aplikasi Django yang khas adalah:

  • /proyek
    • /nama aplikasi
      • models.py
      • views.py
      • / templates
        • index.html
        • dll.
Soviut
sumber
1
+1: Lakukan apa yang Django lakukan secara alami dan hidup jauh lebih sederhana.
S. Lotot
1
Sepakat. Django adalah salah satu kerangka kerja dengan jumlah "ajaib" paling sedikit, tetapi cetakan, tanda cetakan dan aplikasi mempunyai beberapa harapan sebagai bagian dari polanya. Jika Anda harus melakukan inferensi kelas yang aneh, Anda mungkin salah arah.
Soviut