Pythonでクラスのファイルパスを取得するにはどうすればよいですか?


95

PythonでクラスCが与えられた場合、クラスが定義されたファイルをどのように判断できますか?クラスCまたはCのインスタンスから機能するものが必要です。

私がこれをしている理由は、私が同じフォルダに属するファイルを一緒に置くことを好まないからです。Djangoテンプレートを使用して、自分自身をHTMLとしてレンダリングするクラスを作成します。基本実装は、クラスが定義されているファイル名に基づいてテンプレートのファイル名を推測する必要があります。

クラスLocationArtifactをファイル "base / artifacts.py"に置いたとすると、デフォルトの動作はテンプレート名が "base / LocationArtifact.html"になるようにしたいとします。



2
それらはあなたがファイルを探しているモジュールを知っていると仮定します、私はクラスからの実装で作業するときにモジュール文字列を持っています。
Staale 2009年

回答:


130

次のように、inspectモジュールを使用できます。

import inspect
inspect.getfile(C.__class__)

1
私が何をしていたのかわからないが、代わりgetfileに使用する必要があった: inspect.getmodule(C.__class__)
AJP

4
注:ユーザーが作成したクラスでは機能しません
Daniel Braun

6
これはおそらくそうでしょうinspect.getfile(C)Cがクラスの場合、をC.__class__参照するobjectと、例外が発生しTypeError: <module 'builtins' (built-in)> is a built-in classます。インスタンスだけcに使用したいと思いますinspect.getfile(c.__class__)
チェシャーコウ

1
これは、適切なファイルの代わりにmetaclass=abc.ABCMeta返されるため、抽象基本クラス()を拡張するクラスには当てはまりませんでした/usr/local/lib/python3.7/abc.py。@JarretHardie(下記)による解決策はより効果的でした。
martian111

36

試してください:

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

1
C(OPによって所望のように)のインスタンスからのパスを取得するために、交換LocationArtifactobj.__class__objがLocationArtifactのインスタンスです。
martian111

5

これはDjangoにとって間違ったアプローチであり、実際に強制しています。

典型的なDjangoアプリパターンは次のとおりです。

  • /事業
    • / appname
      • models.py
      • views.py
      • / templates
        • index.html

1
+1:Djangoが自然に行うことを行い、人生はとてもシンプルになります。
S.Lott、2009年

1
同意した。Djangoは「マジック」の量が最も少ないフレームワークの1つですが、テンプレート、テンプレートタグ、およびアプリには、パターンの一部としていくつかの期待があります。奇抜なクラス推論をしなければならない場合、おそらく間違った方向に進んでいることになります。
ソビエト連邦2009年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.